翻譯原文地址:https://medium.com/@kostiakoval/load-vs-initialize-a1b3dc7ad6eb
load和initialize方法有什么區(qū)別呢?
已經(jīng)有很多優(yōu)秀的文章討論過這個話題了, 比如Mike Ash 寫的這一篇文章。我就不對細(xì)節(jié)做過多描述了,來看看它們的使用案例吧。
共同點(diǎn)
父類總是比它們的子類先收到調(diào)用消息。
+initialize
1、每個類只調(diào)用一次。
2、如果不去調(diào)用這個類,那它就不會被調(diào)用。
3、+initialize方法可能會被調(diào)用多次。
例如如果一個子類沒有實(shí)現(xiàn)initialize方法,那么父類的initialize會被調(diào)用兩次。
4、第一次調(diào)用這個類的時候,它會被調(diào)用。
5、調(diào)用它是線程安全的。
6、父類總是比它們的子類先收到調(diào)用消息。
+load
1、在app啟動以后,一個類或者Category被加入到Objective-C runtime的時候會去調(diào)用。
2、即使你不調(diào)用一個類的任何方法,也會被調(diào)用。
3、一個類或者Category的load方法只會被系統(tǒng)調(diào)用一次(如果一個Category實(shí)現(xiàn)了+load方法)。
4、Framework里的類在這時候已經(jīng)加載完成了。
5、C++ static initializers 這時候還沒有加載。
6、在main方法前邊被調(diào)用。
7、在這里使用autorelease對象是安全的,因?yàn)锳RC會自動創(chuàng)建autorelease pool 。
用例
+load
- 方法調(diào)用的非常早,可以對類進(jìn)行配置。
- Swizzle方法
+ (void)load
{
NSLog(@"Load KKObject");
[KKObject jr_swizzleMethod:@selector(description) withMethod:@selector(kkk_description) error:nil];
}
Note:在load方法中也建議使用dispatch_once之類的方式來保障這里的內(nèi)容只被執(zhí)行一次,因?yàn)閘oad方法雖然系統(tǒng)只調(diào)用一次,但是也可能被手動調(diào)用。
initialize
- 不要在+initialize方法里做太重的工作。
- 總是需要檢查+initialize是否是被當(dāng)前類調(diào)用。
+ (void)initialize
{
if (self == [KKObject self]) {
// ... do the initialization ...
k_objectName = @"a Name";
}
}
因?yàn)槿绻宇悰]有實(shí)現(xiàn)+initialize方法,父類的+initialize方法會被調(diào)用。
- 初始化類的靜態(tài)變量
使用dispatch_once來初始化,是個好方法。
如果你想實(shí)現(xiàn)“懶加載”方式,創(chuàng)建一個property方法并且總是通過這property方法來訪問這個變量。使用dispatch_once來實(shí)現(xiàn)這個property的訪問。
- (NSString *)localName
{
static NSString *k_localName;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
k_localName = @"Cool local name";
});
return k_localName;
}