if語句
命名
通用的約定
推薦使用長的、描述性的方法和常量
常量使用駝峰式的命名規(guī)范,有時為了清晰,加上所在的類名
Initializer 和 dealloc 初始化
推薦的代碼組織方式:將 dealloc
方法放在實現(xiàn)文件的最前面(直接在 @synthesize
以及 @dynamic
之后),init
應該放在 dealloc
之后。如果有多個初始化方法喘漏, designated initializer 應該放在第一個,secondary initializer 在之后緊隨华烟,這樣邏輯性更好翩迈。
如今有了 ARC,dealloc 方法幾乎不需要實現(xiàn)盔夜,不過把 init 和 dealloc 放在一起可以從視覺上強調(diào)它們是一對的负饲。通常,在 init 方法中做的事情需要在 dealloc 方法中撤銷喂链。
alloc
返十、 init
分別是申請內(nèi)存和初始化,Objective-C的特性兩步創(chuàng)建
-
alloc
表示對象分配內(nèi)存椭微,這個過程涉及分配足夠的可用內(nèi)存來保存對象洞坑,寫入isa
指針,初始化 retain 的計數(shù)蝇率,并且初始化所有實例變量迟杂。 -
init
是表示初始化對象,這意味著把對象放到了一個可用的狀態(tài)本慕。這通常是指把對象的實例變量賦給了可用的值排拷。
Designated 和 Secondary Initializers
Objective-C 有 designated 和 secondary 初始化方法的觀念。
designated 初始化方法是提供所有的參數(shù)锅尘,secondary 初始化方法是一個或多個监氢,并且提供一個或者更多的默認參數(shù)來調(diào)用 designated 初始化方法的初始化方法。
Designated Initializer
一個類應該又且只有一個 designated 初始化方法,其他的初始化方法應該調(diào)用這個 designated 的初始化方法(雖然這個情況有一個例外)
在類繼承中調(diào)用任何 designated 初始化方法都是合法的忙菠,而且應該保證 所有的 designated initializer 在類繼承中是是從祖先(通常是 NSObject
)到你的類向下調(diào)用的何鸡。
實際上這意味著第一個執(zhí)行的初始化代碼是最遠的祖先,然后從頂向下的類繼承牛欢,所有類都有機會執(zhí)行他們特定的初始化代碼。這樣淆游,你在你做你的特定的初始化工作前傍睹,所有你從超類繼承的東西是不可用的狀態(tài)。即使它的狀態(tài)不明確犹菱,所有 Apple 的框架的 Framework 是保證遵守這個約定的拾稳,而且你的類也應該這樣做。
當定義一個新類的時候有三個不同的方式:
- 不需要重載任何初始化函數(shù)
- 重載 designated initializer
- 定義一個新的 designated initializer
在你希望提供你自己的初始化函數(shù)的時候腊脱,你應該遵守這三個步驟來保證正確的性:
- 定義你的 designated initializer访得,確保調(diào)用了直接超類的 designated initializer
- 重載直接超類的 designated initializer。調(diào)用你的新的 designated initializer.
- 為新的 designated initializer 寫文檔
確保在定義新的designated initializer時陕凹,必須重載父類的designated initializer悍抑,否則會出現(xiàn)調(diào)用者使用父類的designated initializer,從而導致沒有初始化成功子類
上述的一個推論是:你應該永遠不從 designated initializer 里面調(diào)用一個 secondary initializer (如果secondary initializer 遵守約定杜耙,它會調(diào)用 designated initializer)搜骡。如果這樣,調(diào)用很可能會調(diào)用一個子類重寫的 init 方法并且陷入無限遞歸之中
可以使用__attribute__
來標示
初始化模式
類簇 (class cluster)[抽象工廠]
an architecture that groups a number of private, concrete subclasses under a public, abstract superclass. (一個在共有的抽象超類下設(shè)置一組私有子類的架構(gòu))
這個模式非常有用佑女,因為它減少了構(gòu)造器調(diào)用中的復雜性记靡,只需要知道接口如何與對象通信,而不需要知道怎么實現(xiàn)团驱。
Class clusters 在 Apple 的Framework 中廣泛使用:一些明顯的例子比如 NSNumber
可以返回不同哦給你的子類摸吠,取決于 數(shù)字類型如何提供 (Integer, Float, etc...) 或者 NSArray
返回不同的最優(yōu)存儲策略的子類。
The beauty of this pattern is that the caller can be completely unaware of the concrete subclass; in fact it can be used when designing a library to be able to swap the underlaying returned class without leaking any implementation detail as long as is respectful of the contract established in the abstract class.
這個模式的精妙的地方在于嚎花,調(diào)用者可以完全不管子類寸痢,事實上,這可以用在設(shè)計一個庫贩幻,可以用來交換實際的返回的類轿腺,而不用去管相關(guān)的細節(jié),因為它們都遵從抽象超類的方法丛楚。
我們的經(jīng)驗是使用類簇可以幫助移除很多條件語句族壳。
@implementation ZOCKintsugiPhotoViewController
- (id)initWithPhotos:(NSArray *)photos
{
if ([self isMemberOfClass:ZOCKintsugiPhotoViewController.class]) {
self = nil;
if ([UIDevice isPad]) {
self = [[ZOCKintsugiPhotoViewController_iPad alloc] initWithPhotos:photos];
}
else {
self = [[ZOCKintsugiPhotoViewController_iPhone alloc] initWithPhotos:photos];
}
return self;
}
return [super initWithNibName:nil bundle:nil];
}
@end
屬性定義
推薦按照下面的格式來定義屬性
@property (nonatomic, readwrite, copy) NSString *name;
屬性的參數(shù)應該按照下面的順序排列: 原子性,讀寫 和 內(nèi)存管理趣些。 這樣做你的屬性更容易修改正確仿荆,并且更好閱讀。
你必須使用 nonatomic
,除非特別需要的情況拢操。在iOS中锦亦,atomic
帶來的鎖特別影響性能。
屬性可以存儲一個代碼塊令境。為了讓它存活到定義的塊的結(jié)束杠园,必須使用 copy
(block 最早在棧里面創(chuàng)建,使用 copy
讓 block 拷貝到堆里面去)
為了完成一個共有的 getter 和一個私有的 setter舔庶,你應該聲明公開的屬性為 readonly
并且在類擴展總重新定義通用的屬性為 readwrite
的抛蚁。
@interface MyClass : NSObject
@property (nonatomic, readonly) NSObject *object
@end
@implementation MyClass ()
@property (nonatomic, readwrite, strong) NSObject *object
@end
如果 BOOL
屬性的名字是描述性的,這個屬性可以省略 "is" 惕橙,但是特定要在 get 訪問器中指定名字瞧甩,如:
@property (assign, getter=isEditable) BOOL editable;
文字和例子是引用 Cocoa Naming Guidelines.
為了避免 @synthesize
的使用,在實現(xiàn)文件中弥鹦,Xcode已經(jīng)自動幫你添加了肚逸。
私有屬性
私有屬性應該在類實現(xiàn)文件的類拓展(class extensions,沒有名字的 categories 中)中彬坏。有名字的 categories(如果 ZOCPrivate
)不應該使用朦促,除非拓展另外的類。