一.代碼命名
一般性原則
最好是既清晰又簡短,但不要為簡短而喪失清晰性。
例如:removeObject:AtIndex:good
remove不清晰;要移除什么?
名稱通常不縮寫,即使名稱很長,也要拼寫完全。
例如:setBackgroundColor:good
setBgColor:不清晰
方法命名
1.一般性規(guī)則
小寫第一個單詞的首字母,大寫隨后單詞的首字母,不使用前綴。
有兩種例外情況:1,方法名以廣為人知的大寫字母縮略詞(如PDF)開頭;2,私有方法可以使用統(tǒng)一的前綴來分組和辨識。
表示對象行為的方法,名稱以動詞開頭:
-(void)removeAllObjects;
名稱中不要出現(xiàn)do或does,因為這些助動詞沒什么實(shí)際意義。也不要在動詞前使用副詞或形容詞修飾。
如果方法返回方法接收者的某個屬性,直接用屬性名稱命名。不要使用get,除非是間接返回一個或多個值。
例如:-(NSSize)cellSize;對
- (NSSize)getCellSize;錯
參數(shù)要用描述該參數(shù)的關(guān)鍵字命名
-(void)sendAction:(SEL)aSelector to:(id)anObject
forAllCells:(BOOL)flag;對
-
(void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;錯
參數(shù)前面的單詞要能描述該參數(shù)。
-(id)viewWithTag:(int)aTag;對
-(id)taggedView:(int)aTag;錯
不要使用and來連接用屬性作參數(shù)關(guān)鍵字
- (int)runModalForDirectory:(NSString *)pathfile:(NSString *)name types:(NSArray *)fileTypes;對
- (int)runModalForDirectory:(NSString *)pathandFile:(NSString *)name andTypes:(NSArray *)fileTypes;錯
如果方法描述兩種獨(dú)立的行為,使用and來串接它們
- (BOOL)openFile:(NSString *)fullPathwithApplication:(NSString *)appName andDeactivate:(BOOL)flag;
2.訪問方法
訪問方法是對象屬性的讀取與設(shè)置方法。其命名有特定的格式依賴于屬性的描述內(nèi)容。
如果屬性是用名詞描述的,則命名格式為:
-(type)noun;
-(void)setNoun:(type)aNoun;
如果屬性是用形容詞描述的,則命名格式為:
-(BOOL)isAdjective;
-(void)setAdjective:(BOOL)flag;
如果屬性是用動詞描述的,則命名格式為:(動詞要用現(xiàn)在時時態(tài))
-(BOOL)verbObject;
-(void)setVerbObject:(BOOL)flag;
不要使用動詞的過去分詞形式作形容詞使用
-(void)setAcceptsGlyphInfo:(BOOL)flag;Right
-(BOOL)acceptsGlyphInfo;Right
-(void)setGlyphInfoAccepted:(BOOL)flag;Wrong
-(BOOL)glyphInfoAccepted;Wrong
可以使用情態(tài)動詞(can,
should, will等)來提高清晰性,但不要使用do或does。
只有在方法需要間接返回多個值的情況下,才使用get
-(void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;
3.委托方法
委托方法是那些在特定事件發(fā)生時可被對象調(diào)用,并聲明在對象的委托類中的方法。它們有獨(dú)特的命名約定,這些命名約定同樣也適用于對象的數(shù)據(jù)源方法。
名稱以標(biāo)示發(fā)送消息的對象的類名開頭,省略類名的前綴并小寫類第一個字符
-(BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
冒號緊跟在類名之后(隨后的那個參數(shù)表示委派的對象)。該規(guī)則不適用于只有一個sender參數(shù)的方法,也不適用于響應(yīng)通知的方法,在這種情況下,方法的唯一參數(shù)表示通知對象。
用于通知委托對象操作即將發(fā)生或已經(jīng)發(fā)生的方法名中要使用did或will
-(NSUndoManager *) windowWillReturnUndoManager:(NSWindow *)window;
用于詢問委托對象可否執(zhí)行某操作的方法名中可使用did或will,但最好使用should
-(BOOL)windowShouldClose:(id)sender;
4.方法參數(shù)
命名方法參數(shù)時要考慮如下規(guī)則:
如同方法名,參數(shù)名小寫第一個單詞的首字符,大寫后繼單詞的首字符。應(yīng)選擇與方法名連在一起讀起來通順的參數(shù)名。
如:removeObject:(id)anObject
不要在參數(shù)名中使用pointer或ptr,讓參數(shù)的類型來說明它是指針
避免使用one, two,...,作為參數(shù)名
避免為節(jié)省幾個字符而縮寫
實(shí)例變量與常量
聲明屬性和實(shí)例變量
如果屬性是用一個名詞或動詞描述的,格式是:
@property(…) type nounOrVerb;
例如:@property (strong) NSString *title;
@property (assign) BOOLshowsAlpha;
如果聲明的屬性是用一個形容詞描述的,并且屬性名稱省略了”is”前綴,則指定其getter方法。
例如:@property (assign, getter=isEditable) BOOL editable;
在為類添加實(shí)例變量應(yīng)注意:
避免創(chuàng)建public實(shí)例變量
使用@private、@protected顯示限定實(shí)例變量的訪問權(quán)限。如果你希望你的類將被繼承,而這些子類將需要直接訪問數(shù)據(jù),使用@protected指令。
常量
枚舉常量
使用枚舉來定義一組相關(guān)的整數(shù)常量,枚舉常量也要有相應(yīng)的前綴。大寫前綴后緊跟的第一個單詞首字母。
其他常量
使用const來修飾浮點(diǎn)常量或彼此沒有關(guān)聯(lián)的整數(shù)常量。
const常量命名范例:
const float NSLightGray;
避免在程序中直接出現(xiàn)常量,使用超過一次的應(yīng)以宏定義的形式來替代。宏定義的命名應(yīng)當(dāng)能夠表達(dá)出它的用途,并且用大寫字母表示。
二.書寫規(guī)范
1.方法聲明與定義
方法中如果一行有非常多的參數(shù),更好的方式是將每個參數(shù)單獨(dú)拆成一行。如果使用多行,將每個參數(shù)前的冒號對齊。
- (void)doSomethingWith:(GTMFoo *)theFoo
rect:(NSRect)theRect
interval:(float)theInterval { ...
}
當(dāng)?shù)谝粋€關(guān)鍵字比其它的短時,保證下一行至少有4個空格的縮進(jìn)。這樣可以使關(guān)鍵字垂直對齊,而不是使用冒號對齊:
-(void)short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval{ ...
}
-或者+與返回類型之間,需要有空格。參數(shù)列表中,只有參數(shù)之間有空格。
2.方法調(diào)用
方法調(diào)用時,所有參數(shù)應(yīng)該在同一行。
[myObjectdoFooWith:arg1 name:arg2 error:arg3];
或者每行一個參數(shù),以冒號對齊:
[myObjectdoFooWith:arg1
name:arg2
error:arg3];
與方法定義和方法聲明一樣,當(dāng)關(guān)鍵字的長度不足以以冒號對齊時,下一行都要以四個空格進(jìn)行縮進(jìn)。
[myObjshort:arg1
longKeyword:arg2
evenLongerKeyword:arg3];
3.變量的聲明
變量名必須起有意義的名字,使其它人可以很容易讀懂變量所代表的意義。與方法命名一樣,首字母小寫。
對于一些特殊類型的變量,命名時要帶上類型,如NSArray的變量命名為xxxArray,其他的如xxxDictionary,xxxSize等。這樣就可以從名稱上知道是什么類型的變量。千萬不能將NSArray的變量命名為xxxDictionary。
成員變量使用“_”作為前綴。
三.編碼的排版格式
1空格的使用
代碼的縮進(jìn)應(yīng)使用空格(SPACE),不能使用制表符(TAB),并且縮進(jìn)以2個字符為單位。
關(guān)鍵字與其后的表達(dá)式之間要有空格,如:if (expr)或for (expr)
單目操作符不應(yīng)與它們的操作數(shù)分開(如’!’和’^’等)。
除‘,’外,其它雙目操作符應(yīng)與它們的操作數(shù)用空格隔開。如:
i=i+1;//錯誤的寫法,操作符兩端沒有空格
i = i + 1;//正確的寫法
if(a>b)//錯誤的寫法,邏輯判斷符號兩端沒有空格
if(a > b)//正確的寫法
.h中協(xié)議<>前面有一個空格。
.h中成員聲明時,類型與變量之間至少有1個空格。*號靠近變量,不靠近類型。
@property后留1個空格,()里面,逗號緊跟前一變量,與后一變量之間留1個空格。()外面,先留1個空格,再聲明屬性。
方法的+,-后面與()之間留1個空格。
返回類型與*之間留1個空格,方法參數(shù)中返回類型與*之間留1個空格。
在多參數(shù)方法中,每個參數(shù)后面都有1個空格。
2關(guān)于空行
1) .h中的空行
文件說明與#import之間空1行
#import之間,如果需要分類區(qū)別,各類別之間空1行。
#import與@class之間空2行。
@interface與@class之間空1行。
頭文件{}里面,空1行開始聲明對象成員,如果需要分類區(qū)別,各類別之間空1行。
頭文件{}外,空1行書寫屬性,如果需要分類區(qū)別,各類別之間空1行。
屬性下面空1行開始寫方法,如果需要分類區(qū)別,各類別之間空1行。
方法聲明完后,與@end空1行。
如果需要聲明protocol,空2行接著寫。通常protocol寫在@end后面,但是聲明在@interface之前。
2) .m中的空行
文件說明與#import之間空1行
#import之間,如果需要分類區(qū)別,各類別之間空1行。
@implementation和@synthesize之間空1行,如果需要分類區(qū)別,各類別之間空1行。
@synthesize與方法之間空1行。
方法與方法之間空1行。
3)方法里面的空行
變量聲明后需要空1行,如果需要分類區(qū)別,各類別之間空1行。
條件、循環(huán)和選擇語句,整個語句結(jié)束,需要空1行。
各功能塊之間空1行。
最后一個括弧之前不空行。
注釋與代碼之間不空行。
#pragma mark與方法之間空1行。
4)每行代碼最好不超過100個字符。
四.注意事項
1.BOOL
Ojbective-C中定義BOOL為無符號字符型,這意味著BOOL類型可以有不同于1或者0的值。不要直接把整形轉(zhuǎn)換成BOOL。常見的錯誤包括將數(shù)組的大小、指針值及位運(yùn)算的結(jié)果直接轉(zhuǎn)換成BOOL,這取決于整型結(jié)果的最后一個字節(jié),可能產(chǎn)生一個NO的值。當(dāng)轉(zhuǎn)換整形至BOOL時,使用三目操作符來返回YES或者NO。
對BOOL使用邏輯運(yùn)算符(&&,||和!)是合法的,返回值也可以安全地轉(zhuǎn)換成BOOL,不需要使用三目操作符。
錯誤的用法:
-(BOOL)isBold {
return[self fontTraits] & NSFontBoldTrait;}
-(BOOL)isValid {
return[self stringValue]; }
正確的用法:
-(BOOL)isBold {
return([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
-(BOOL)isEnabled {
return[self isValid] && [self isBold];
}
同樣的,不要直接比較BOOL變量與YES/NO。不僅影響可讀性,結(jié)果可能與你想的不同。
錯誤的用法:
BOOLgreat = [foo isGreat];
if(great == YES)
正確的用法:
BOOLgreat = [foo isGreat];
if(great)
2.點(diǎn)引用
點(diǎn)引用是Objective-C2.0的風(fēng)格,它被使用于簡單的屬性set、get操作,但對象的其他行為不應(yīng)該使用它。
正確的做法:
NSString*oldName = myObject.name;
myObject.name= @"Alice";
錯誤的做法:
NSArray*array = [NSArray arrayWithObject:@"hello"];
NSUIntegernumberOfItems = array.count;// not aproperty
array.release;// nota property
????t?#