命名規(guī)則 - Conventions

2018-08-12 21:19 更新

命名規(guī)則 - Conventions

使用框架類時(shí),你會(huì)發(fā)現(xiàn) Objective-C 代碼非常易于閱讀。它的類名和方法名比一般的 C 語(yǔ)言函數(shù)或 C 標(biāo)準(zhǔn)庫(kù)要更加具有描述性。Camel Case 適用于帶有多個(gè)單詞的名稱。在編寫(xiě)類的時(shí)候,你應(yīng)當(dāng)使用與 Cocoa 和 Cocoa Touch 相同的規(guī)則,這樣可以使你的代碼對(duì)于你和其他需要與你協(xié)同工作的 Objective-C 開(kāi)發(fā)者來(lái)說(shuō)更加易讀,并且可以保證代碼庫(kù)的一致性。

此外,請(qǐng)嚴(yán)格遵循命名規(guī)則,保證 Objective-C 框架功能的各種機(jī)制的正常工作。例如,訪問(wèn)方法的名稱必須遵循命名規(guī)則來(lái)命名才能在 Key-Value Coding(KVC)或 Key-Value Observing(KVO)機(jī)制下正常工作。

本章介紹了一些廣泛運(yùn)用于 Cocoa 及 Cocoa Touch 編碼中的命名規(guī)則,也列舉了需要在整個(gè)應(yīng)用程序項(xiàng)目(包括使用到的框架類)中唯一命名的情況。

一些名稱必須在程序中唯一

創(chuàng)建一個(gè)新的類別、符號(hào)或是標(biāo)識(shí)符時(shí),你必須先考慮它的名稱在所屬區(qū)域中是否唯一。這個(gè)區(qū)域可能是整個(gè)應(yīng)用程序(包括所涉及到的框架類);也有可能僅僅是一個(gè)封裝的類或是一個(gè)代碼塊。

類名應(yīng)在程序中唯一

不論是在項(xiàng)目中還是在項(xiàng)目所包含的框架或 bundle 中,Objective-C 中的類名必須是唯一的。例如,避免使用如 ViewController 或 TextParser 作為類名,因?yàn)檫@些名稱有可能是包含在 App 中的一個(gè)框架名。

在命名類時(shí)使用前綴命名可以保證類名唯一。你會(huì)注意到 Cocoa 及 Cocoa Touch 的類名通常都以 NS 或 UI開(kāi)頭。像這樣兩個(gè)字符組成前綴的命名方式在 Apple 中專門(mén)為框架類而保留。隨著你學(xué)習(xí)更多關(guān)于 Cocoa 及 Cocoa Touch 的知識(shí),你會(huì)遇到一些其他的特定框架的前綴,如下表所示。

Prefix Framework
NS Foundation (OS X and iOS) and Application Kit (OS X)
UI UIKit (iOS)
AB Address Book
CA Core Animation
CI Core Image

而你所創(chuàng)建的類的命名必須使用三個(gè)字符組成的前綴,可以是你的公司名和 App 名的結(jié)合,也可以是你的 App 中的某個(gè)組成部分。例如,如果你的公司叫做 Whispering Oak,你正在開(kāi)發(fā)的一個(gè)游戲叫做 Zebra Surprise,那么你可以使用 WZS 或 WOZ 作為類名的前綴。

此外,你應(yīng)該盡可能使用名詞來(lái)命名你的類名,這樣可以明確地顯示這個(gè)類所代表的含義。例如下表中來(lái)自 Cocoa 及 Cocoa Touch中的例子。

NSWindow CAAnimation: NSWindowController NSManagedObjectContext

如果你需要使用多個(gè)單詞來(lái)命名你的類,那么每個(gè)單詞的首字母必須是大寫(xiě)。

類中的方法名應(yīng)具描述性且唯一

在保證了類名唯一后,同時(shí)這個(gè)類中所定義的方法名也必須是唯一的,但它可以與其他類中的某一個(gè)方法名相同。例如復(fù)寫(xiě)一個(gè)父類方法或是使用多態(tài)方法的情況。在不同類中具有相同功能的方法應(yīng)當(dāng)有相同的方法名、返回類型和參數(shù)類型。

方法名不需要包含前綴,且應(yīng)當(dāng)以小寫(xiě)字母開(kāi)頭,而對(duì)于多單詞組成的名稱,后續(xù)單詞的首字母應(yīng)該大寫(xiě)。下表為 NSString 類中的方法的命名。

length characterAtIndex: lengthOfBytesUsingEncoding:

如果一個(gè)方法中帶有多個(gè)參數(shù),那么方法名中必須提示每一個(gè)參數(shù):

substringFromIndex: writeToURL:atomically:encoding:error: enumerateSubstringsInRange:options:usingBlock:

方法名的第一部分提示方法的主要作用或提示方法調(diào)用后的結(jié)果。例如,如果一個(gè)方法在調(diào)用后返回一個(gè)值,那么第一個(gè)單詞應(yīng)當(dāng)表明該返回值的類型,如上文表格中的方法名 length,character...,substring...等等;如果你還需要在方法名中提示一些關(guān)于這個(gè)返回值的信息,那么應(yīng)當(dāng)使用多個(gè)單詞來(lái)命名方法,如 NSString 類中的 mutableCopy 方法,capitalizedString 方法和 lastPathComponent 方法;如果一個(gè)方法用于執(zhí)行某個(gè)操作,如寫(xiě)磁盤(pán)或列舉目錄,那么方法名的第一個(gè)單詞必須提示這個(gè)操作,如 write... 方法或 enumerate... 方法。

如果方法中含有一個(gè) error 指針參數(shù)來(lái)指示錯(cuò)誤,那么應(yīng)在其名稱的最后加上 error 參數(shù);如果方法中使用了 block,同樣,為了使得能夠應(yīng)在方法名的最后加上 blcok 參數(shù)。

使用一個(gè)能夠清楚表明方法的作用但又簡(jiǎn)潔明了的方法名非常重要,這不代表你需要取一個(gè)冗長(zhǎng)的方法名,而同時(shí)方法名過(guò)于簡(jiǎn)潔明了也無(wú)法很好地表明一個(gè)方法的含義,因此最佳的方法是在這二者中找尋平衡點(diǎn),如:

stringAfterFindingAndReplacingAllOccurrencesOfThisString:withThisString Too verbose
strReplacingStr:str: Too concise
stringByReplacingOccurrencesOfString:withString: Just right

除非在不同語(yǔ)言和文化中某個(gè)單詞的縮寫(xiě)是眾所周知的,否則你應(yīng)當(dāng)避免在方法名中使用縮寫(xiě)。這里提供了一個(gè)常見(jiàn)縮寫(xiě)的列表:Acceptable Abbreviations and Acronyms。

在框架類的 Categories 中使用前綴命名方法

當(dāng)使用 Category 來(lái)創(chuàng)建方法到一個(gè)已經(jīng)存在的框架類時(shí),你需要在方法名中使用前綴來(lái)避免沖突。

同一區(qū)域內(nèi)局部變量名必須唯一

由于 Objective-C 是 C 語(yǔ)言擴(kuò)展而來(lái),因此 Objective-C 同樣要遵守 C 語(yǔ)言中的變量命名規(guī)則。一個(gè)局部變量的變量名不允許與在相同范圍內(nèi)聲明的其他變量名沖突。

(void)someMethod {
    int interestingNumber = 42;
    ...
    int interestingNumber = 44; // not allowed
}

盡管 C 語(yǔ)言允許一個(gè)局部變量的變量名與封裝區(qū)域中的變量名相同。如下:

(void)someMethod {
    int interestingNumber = 42;
    ...
    for (NSNumber *eachNumber in array) {
        int interestingNumber = [eachNumber intValue]; // not advisable
        ...
    }
}

但這樣會(huì)使得代碼段變得混亂,不易于閱讀,所以在編碼中請(qǐng)盡量避免這種情況。

方法名

與類的命名相同,除了考慮唯一性之外,方法的命名還應(yīng)該遵循嚴(yán)格的命名規(guī)則。除了 Cocoa 和 Cocoa Touch 的要求外,這些規(guī)則是為了滿足一些 Objective-C 的基礎(chǔ)機(jī)制,如編譯和運(yùn)行。

訪問(wèn)方法的名稱

使用 @property 語(yǔ)法來(lái)聲明對(duì)象的屬性時(shí)(如 Encapsulating Data),編譯器會(huì)自動(dòng)合成 getter 和 setter 方法。如果你需要使用自己提供的訪問(wèn)方法,那么你需要保證一個(gè)每一個(gè)屬性都使用了正確的方法名,這樣方法才可以被語(yǔ)法點(diǎn)調(diào)用。

除個(gè)別特殊情況之外,一個(gè) getter 方法必須使用與屬性相同的名稱。例如,一個(gè)屬性名為 firstname,那么它的訪問(wèn)方法名稱也應(yīng)為 firstname。但 Boolean 屬性是一個(gè)特例,因?yàn)?Boolean 屬性的 getter 方法名以 is 開(kāi)頭。例如,一個(gè)屬性名為 paused,那么它的 getter 方法名為 isPaused。

一個(gè)屬性的 setter 方法命名應(yīng)使用形如 setPropertyName: 的形式。譬如,一個(gè)屬性名為 firstname,那么它的 setter 方法應(yīng)為 setFirstName:;同樣對(duì)于一個(gè) Boolean 型的屬性 paused 而言,相應(yīng)的 setter 方法應(yīng)為 setPaused:。

盡管使用 @property 語(yǔ)法能夠方便地設(shè)定不同的訪問(wèn)方法名稱(你只需要特殊考慮 Boolean 型的情況),但你還是需要注意下述的一些規(guī)則,以免如 Key Value Coding(getter 名為 valueForKey:,setter名為 setValue:forKey:) 這樣的機(jī)制無(wú)法正常工作。了解更多有關(guān) KVC 的信息,查閱 Key-Value Coding Programming Guide 。

創(chuàng)建對(duì)象的方法名

在之前的一些章節(jié)中介紹了許多不同創(chuàng)建一個(gè)類的實(shí)例的方法,你可以同時(shí)分配空間和初始化,例如:

NSMutableArray *array = [[NSMutableArray alloc] init];

或者你可以使用 new 方法來(lái)分配空間和初始化:

NSMutableArray *array = [NSMutableArray new];

一些類還提供了 class factory 方法:

NSMutableArray *array = [NSMutableArray array];

創(chuàng)建 class facotry 方法應(yīng)以其所創(chuàng)建的類的名稱開(kāi)頭(不使用前綴),以 NSArray 類為例,它的 factory 方法以 array 開(kāi)頭。而 NSMutableArray 類不定義任何它的類依賴 factory 方法,因此它創(chuàng)建一個(gè)可變 array 的 factory 方法仍然以 array 開(kāi)頭。

Objective-C 有許多不同的內(nèi)存管理規(guī)則,這些規(guī)則讓編譯器能夠保證對(duì)象有足夠的的內(nèi)存空間。編譯器會(huì)根據(jù)創(chuàng)建方法的名稱來(lái)判斷遵循哪一條規(guī)則。因?yàn)?autorelease pool blocks 不同,由 factory 方法創(chuàng)建的對(duì)象與由傳統(tǒng)的分配空間、初始化或 new 方法得來(lái)的對(duì)象在管理上會(huì)有細(xì)微的區(qū)別。學(xué)習(xí)更多有關(guān) autorelease pool blocks 和一般的內(nèi)存管理知識(shí),查閱 Advanced Memory Management Programming Guide

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)