所有的變量均指參數(shù)
“方法” 可能是你的程序中最常用的元素, 因此你應(yīng)該特別關(guān)注 “如何命名它們”. 本章節(jié)將討論方法命名的以下方面:
一般性規(guī)則
當(dāng)你命名方法時(shí),有一些準(zhǔn)則需要記在頭腦里.
方法名稱以小寫字母開頭, 后續(xù)單詞的首字母大寫(駝峰). 不要使用前綴.
對(duì)于這些準(zhǔn)則有兩個(gè)明確的例外. 你可以以一個(gè)眾所周知的大寫首字母縮略詞(比如 TIFF或者PDF)作為方法的開頭, 你也可以使用前綴來進(jìn)行分組并區(qū)分私有方法.
對(duì)于表示 一個(gè)對(duì)象所采取的動(dòng)作的方法, 以動(dòng)詞開頭
- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem;
不要使用’do’或者’does’作為名稱的一部分,因?yàn)檫@些輔助性動(dòng)詞并不能增加任何意思.
如果方法返回調(diào)用者的一個(gè)屬性, 那么就以這種屬性命名這個(gè)方法. 不必使用’get’, 除非間接返回一個(gè)或多個(gè)值.
- (NSSize)cellSize;? ? ? ? ? 正確
- (NSSize)calcCellSize;? ? ? 錯(cuò)誤
- (NSSize)getCellSize;? ? ? 錯(cuò)誤
在所有的變量之前使用關(guān)鍵字
- (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag;? ? ? ? ? 正確
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 錯(cuò)誤
在變量之前用一個(gè)詞來描述變量
- (id)viewWithTag:(NSInteger)aTag;? ? 正確
- (id)taggedView:(int)aTag;? ? ? ? ? 錯(cuò)誤
當(dāng)你創(chuàng)建一個(gè)比被繼承方法更加明確的方法時(shí),你需要在被繼承方法后添加新的關(guān)鍵字
- (id)initWithFrame:(CGRect)frameRect;? ? ? ? ? ? ? ? ? ? NSView, UIView.
- (id)initWithFrame:(NSRect)frameRect mode:(int)aMode cellClass:(Class)factoryId numberOfRows:(int)rowsHigh numberOfColumns:(int)colsWide;? ? ? ? ? ? NSMatrix,? NSView的子類
不要使用’and’來連接屬于調(diào)用者屬性的關(guān)鍵字
( 換句話說, 如果這個(gè)參數(shù)是調(diào)用者的屬性, 則不需要用and來連接)
- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes;? ? ? ? ? ? ? 正確
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;? ? ? ? 錯(cuò)誤
盡管’and’在這個(gè)例子中看起來很不錯(cuò), 但是當(dāng)你創(chuàng)建一個(gè)有更多更多關(guān)鍵字的方法時(shí)就會(huì)產(chǎn)生問題.
如果方法描述了兩個(gè)單獨(dú)的動(dòng)作, 使用’and’來連接
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;? ? ? ? ? NSWorkspace
存取方法
存取方法指 可以設(shè)置和返回一個(gè)對(duì)象屬性的方法. 他們有明確被推薦的格式, 具體采取哪種格式, 取決于我們?nèi)绾伪磉_(dá)屬性.
如果屬性表達(dá)為名詞, 格式為:
- (type)noun;
- (void)setNoun:(type)aNoun;
比如:
- (NSString *)title;
- (void)setTitle:(NSString *)aTitle;
如果屬性表達(dá)為形容詞, 格式為:
(平時(shí)我們所指的 BOOL 值, can類型屬性)
- (BOOL)isAdjective;
- (void)setAdjective:(BOOL)flag;
比如:
- (BOOL)isEditable;
- (void)setEditable:(BOOL)flag;
如果屬性表達(dá)為動(dòng)詞, 格式為:
- (BOOL)verbObject;
- (void)setVerbObject:(BOOL)flag;
比如:
- (BOOL)showsAlpha;
- (void)setShowsAlpha:(BOOL)flag;
動(dòng)詞應(yīng)該用一般現(xiàn)在時(shí).
不要使用分詞將動(dòng)詞變成形容詞
(分詞指 以ing, ed 等形式結(jié)尾的動(dòng)詞, 可表 形容詞 或者 時(shí)態(tài) 使用)
- (void)setAcceptsGlyphInfo:(BOOL)flag;? ? ? ? 正確
- (BOOL)acceptsGlyphInfo;? 正確
- (void)setGlyphInfoAccepted:(BOOL)flag;? 錯(cuò)誤
- (BOOL)glyphInfoAccepted;? 錯(cuò)誤
你可以通過使用情態(tài)動(dòng)詞(比如 can, should, will 等等)來明確意思, 但是不要使用’do’ 或者 ‘does’
- (void)setCanHide:(BOOL)flag;? ? ? 正確
- (BOOL)canHide;? ? ? 正確
- (void)setShouldCloseDocument:(BOOL)flag;? ? 正確
- (BOOL)shouldCloseDocument;? ? 正確
- (void)setDoesAcceptGlyphInfo:(BOOL)flag;? 錯(cuò)誤
- (BOOL)doesAcceptGlyphInfo;? ? 錯(cuò)誤
對(duì)于間接返回 對(duì)象和值的方法, 使用’get’. 當(dāng)有多個(gè)參數(shù)需要返回的時(shí)候,你應(yīng)該使用下面這種格式.
(最前面一個(gè)參數(shù)使用get, 后面需要返回的參數(shù)是指針 且 不加and)
- (void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;? NSBezierPath
對(duì)于這樣的方法, 應(yīng)該接受為NULL的輸入和輸出參數(shù), 以表明調(diào)用者對(duì)一個(gè)或者多個(gè)返回值不感興趣.
代理方法
代理方法是指 當(dāng)確定事件發(fā)生時(shí),對(duì)象在其代理中回調(diào)的方法(如果代理對(duì)象有實(shí)現(xiàn)相應(yīng)方法). 他們有與眾不同的格式, 這個(gè)同樣也適用于對(duì)象數(shù)據(jù)源中回調(diào)的方法.
以 標(biāo)識(shí)正在發(fā)送消息的對(duì)象所屬的類 開頭
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
類名去除前綴 并且 第一個(gè)單詞小寫
如果方法只有一個(gè)參數(shù),即調(diào)用者, 則在類名后面直接添加冒號(hào):
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
這種情況的一個(gè)例外是 由于發(fā)布通知而回調(diào)的方法. 在這種情況下, 唯一的參數(shù)就是通知對(duì)象
- (void)windowDidChangeScreen:(NSNotification *)notification;
使用’did’或者’will’通知代理被回調(diào)的方法是已經(jīng)發(fā)生還是即將發(fā)生.
- (void)browserDidScroll:(NSBrowser *)sender;
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;
盡管你可以對(duì)回調(diào)方法使用’did’或者’will’來告訴代理所代表的對(duì)象做某事, 但是此時(shí)’should’更好.
(這句話翻譯過來比較奇怪, 直接看代碼比較好理解. 也就是 self.delegate的self(代理所代表的對(duì)象) close(做某事))
- (BOOL)windowShouldClose:(id)sender;
集合方法
對(duì)于管理一個(gè)對(duì)象集合的對(duì)象, 以下方法的格式是約定寫法:
- (void)addElement:(elementType)anObj;
- (void)removeElement:(elementType)anObj;
- (NSArray *)elements;
For example:
- (void)addLayoutManager:(NSLayoutManager *)obj;
- (void)removeLayoutManager:(NSLayoutManager *)obj;
- (NSArray *)layoutManagers;
對(duì)于這個(gè)準(zhǔn)則而言, 下面是一些限制
如果集合是真正無序的, 返回一個(gè)NSSet對(duì)象而不是NSArray對(duì)象
如果把元素插入在集合中明確的位置是很重要的, 那么使用下面類似的方法 而不是上面的任一個(gè)
- (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index;
- (void)removeLayoutManagerAtIndex:(int)index;
在集合相關(guān)的方法中有一些實(shí)現(xiàn)細(xì)節(jié)需要記住:
這些方法(增刪)通常意味著被插入對(duì)象的所有權(quán), 因此添加/插入對(duì)象必須retain(保留)此對(duì)象, 刪除對(duì)象也必須release(釋放)此對(duì)象.
如果被插入對(duì)象需要給主對(duì)象返回一個(gè)指針, 通常來說你需要一個(gè)set方法,此方法返回一個(gè)指針但是不retain(保留)此對(duì)象. 在insertLayoutManager:atIndex 方法中, NSLayoutManager類就是這么做的.
- (void)setTextStorage:(NSTextStorage *)textStorage;
- (NSTextStorage *)textStorage;
通常來說, 你不會(huì)直接調(diào)用setTextStorage: 方法, 而是會(huì)選擇重寫它.
另一個(gè)關(guān)于集合方法的慣例寫法來自NSWindow
- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
- (void)removeChildWindow:(NSWindow *)childWin;
- (NSArray *)childWindows;
- (NSWindow *)parentWindow;
- (void)setParentWindow:(NSWindow *)window;
方法參數(shù)
下面是一些有關(guān)方法參數(shù)名的一般性規(guī)則:
與方法一樣, 參數(shù)也以小寫字母開頭, 后面連續(xù)的單詞第一個(gè)字母大寫
不要在名字中使用’pointer’或者’ptr’. 要讓參數(shù)類型而不是參數(shù)名來表明它是否是一個(gè)指針
避免使用一個(gè)和兩個(gè)單詞名作為參數(shù)
避免只使用幾個(gè)字母的縮寫
通常, 下面的關(guān)鍵字和變量會(huì)被一起使用:
...action:(SEL)aSelector
...alignment:(int)mode
...atIndex:(int)index
...content:(NSRect)aRect
...doubleValue:(double)aDouble
...floatValue:(float)aFloat
...font:(NSFont *)fontObj
...frame:(NSRect)frameRect
...intValue:(int)anInt
...keyEquivalent:(NSString *)charCode
...length:(int)numBytes
...point:(NSPoint)aPoint
...stringValue:(NSString *)aString
...tag:(int)anInt
...target:(id)anObject
...title:(NSString *)aString
私有方法
大多數(shù)情況下, 私有方法名和公開方法名遵守相同的規(guī)則. 然而, 一個(gè)共同的約定是 私有方法需要有一個(gè)前綴用以更簡(jiǎn)單的和公開方法進(jìn)行區(qū)分. 即使有這個(gè)約定, 私有方法名也可能造成一個(gè)奇怪的類型問題. 當(dāng)你設(shè)計(jì)一個(gè)Cocoa 框架子類的時(shí)候, 你無法得知是否你的私有方法無意中重寫了私有框架中同名的方法.
Cocoa框架中大多數(shù)私有方法的名稱都有下劃線前綴,以將它們標(biāo)記為私有.
不要使用下劃線作為你私有變量的前綴. 蘋果保留這一慣例.
如果你正在子類化一個(gè)大的Cocoa框架類(比如UIView或者NSView)并且你想要完全確保你的私有方法和父類中方法不同, 你可以在你的私有方法前添加自己的前綴. 前綴應(yīng)該盡可能獨(dú)一無二, 可以基于你的公司或者項(xiàng)目并且形式為”XX”.