第七章 系統框架—第51條:精簡initialize與load實現代碼

有時候,類必須先執行某些初始化操作,然后才能正常使用。在Objective-C中,絕大多數類都繼承自NSObject這個根類,而該類有兩個方法,可用來實現這種初始化操作。

load方法:

+ (void)load

對于加入運行期系統中的每個類及分類來說,必定會調用此方法,而且僅調用一次。當包含類或分類的程序庫載入系統時,就會執行此方法,而這通常就是指應用程序啟動的時候。如果分類和其所屬的類都定義了load方法,則先調用類里的,再調用分類里的。
load方法的問題在于,執行該方法時,運行期系統處于"脆弱狀態"。在執行子類的load方法之前,必定會先執行所有超類的load方法,而如果代碼還依賴了其他程序庫,那么程序里相關類的load方法也必定會先執行。然而,根據某個給定的程序庫,卻無法判斷出其中各個類的載入順序。因此,在load方法中使用其他類是不安全的。
需要注意的是,load方法并不像普通的方法那樣,它并不遵從那套繼承規則。如果某個類本身沒有實現load方法,那么不管其各級超類是否實現此方法,系統都不會調用。此外,分類和其所屬的類里,都可能出現load方法,此時兩種實現代碼都會調用,類的實現比分類的實現先執行。
而且load方法務必實現得精簡一些,也就是盡量減少其所執行的操作,因為整個應用程序在執行load方法時都會阻塞。如果load方法中包含繁雜的代碼,那么應用程序在執行期間就會變得無響應。不要在里面等待鎖,也不要調用可能會加鎖的方法。總之,能不做的事情就別做。實際上,凡是想通過load在類加載之前執行某些任務的,基本都做得不太對。其真正用途僅在于調試程序。

想執行與類相關的初始化操作,還有個辦法,就是覆寫下列方法:

+ (void)initialize

對于每個類來說,該方法會在程序首次用該類之前調用,且只調用一次。它是由運行期系統來調用的,絕不應該通過代碼直接調用。其雖與load相似,但卻有幾個非常重要的微妙區別。首先,它是"惰性調用的",也就是說,只有當程序用到了相關的類時,才會調用。因此,如果某個類一直都沒有使用,那么其initialize方法就一直不會運行。這也就等于說,應用程序無須想把每個類的initialize都執行一遍,這與load方法不同,對于load來說,應用程序必須阻塞并等著所有類的load都執行完,才能繼續。
此方法與load還有個區別,就是運行期系統在執行該方法時,是處于正常狀態的,因此,從運行期系統完整度上來講,此時可以安全使用并調用任意類中的任意方法。而且,運行期系統也能給你確保initialize方法一定會在"線程安全環境"中執行,這就是說,只有執行initialize的那個線程可以操作類或類實例。其他線程都要先阻塞,等著initialize執行完。
最后一個區別是: initialize方法與其他消息一樣,如果某個類未實現它,而其超類實現了,那么就會運行超類的實現代碼。

#import <Foundation/Foundation.h>

@interface EOCBaseClass : NSObject
@end

@implementation EOCBaseClass
+ (void)initialize {
    NSLog(@"%@ initialize", self);
}
@end

@interface EOCSubClass : EOCBaseClass
@end

@implementation EOCSubClass
@end

即便EOCSubClass類沒有實現initialize方法,它也會收到這條消息。由各級超類所實現的initialize也會先行調用。所以,首次使用EOCSubClass時,控制臺會輸出如下消息:

EOCBaseClass initialize
EOCSubClass initialize

與其他方法(除去load)一樣,initialize也遵循通常的繼承規則,所以,當初始化基類EOCBaseClass時,EOCBaseClass中定義的initialize方法要運行一遍,而當初始化子類EOCSubClass時,由于該類并未覆寫此方法,因而還要把父類的實現代碼再運行一遍。鑒于此,通常都會這么來實現initialize方法:

+ (void)initialize {
    if (self == [EOCBaseClass class]) {
        NSLog(@"%@ initialized", self);
    }
}

加上這條檢測語句之后,只有當開發者所期望的那個類載入系統時,才會執行相關的初始化操作。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容