?load 方法菱农,其原型如下:
? +(void)load;
?? 對(duì)于加入運(yùn)行期系統(tǒng)中的每個(gè)類及分類來(lái)說(shuō),必定會(huì)調(diào)用此方法究履,而且僅調(diào)用一次妹笆。如果分類和其所屬的類都定義了load方法泼返,則先調(diào)用類里的,在調(diào)用分類的赏壹。
?? load方法的問(wèn)題在于炊甲,執(zhí)行該方法時(shí)泥彤,運(yùn)行期系統(tǒng)處于“脆弱狀態(tài)”。在執(zhí)行子類的load方法之前卿啡,必定會(huì)先執(zhí)行所有超類的load方法吟吝,而如果代碼還依賴了其他程序庫(kù),那么程序庫(kù)里相關(guān)類的load方法也必定會(huì)先執(zhí)行颈娜。然而剑逃,根據(jù)某個(gè)給定的程序庫(kù),卻無(wú)法判斷出其中各個(gè)類的載入順序揭鳞。因此炕贵,在load方法中使用其他類是不安全的。如下斷代碼:
?? #import <Foundation/Foundation.h>
?? #import "ClassA.h"
?? @interface ClassB : NSObject
?? @end
?? @implementation ClassB
?? +(void)load {
?????? NSLog(@"Loading ClassB");
?????? ClassA *object = [ClassA new];
?? }
?? @end
? 此處使用NSLog沒(méi)有問(wèn)題野崇,而且相關(guān)字符串也會(huì)照常記錄称开,因?yàn)镕oundation框架肯定在運(yùn)行l(wèi)oad方法之前就已經(jīng)載入系統(tǒng)了。但是乓梨,在ClassB的load方法里使用ClassA卻不太安全鳖轰,因?yàn)闊o(wú)法確定在執(zhí)行ClassB的load方法之前,ClassA是不是加載好了扶镀。
? 還有一點(diǎn)需要注意的是蕴侣,load方法并不想普通方法那樣,它并不遵從繼承規(guī)則臭觉。如果某各類本身沒(méi)有實(shí)現(xiàn)load方法昆雀,那么不管其各超類是否實(shí)現(xiàn)此方法辱志,系統(tǒng)都不會(huì)調(diào)用。此外狞膘,分類和其所屬的類里揩懒,都可能出現(xiàn)load方法。此時(shí)兩種實(shí)現(xiàn)代碼都會(huì)調(diào)用挽封,類的實(shí)現(xiàn)要比分類的實(shí)現(xiàn)先調(diào)用已球。
? 整個(gè)應(yīng)用在執(zhí)行l(wèi)oad方法是都會(huì)阻塞,如果load方法中包含繁雜的代碼辅愿,那么應(yīng)用程序在執(zhí)行期間就會(huì)變得無(wú)響應(yīng)智亮。不要在里面等待鎖,也不要調(diào)用可能會(huì)加鎖的方法点待±龋總之,能不做的事情就別做亦鳞。其真正的用途僅在于調(diào)試程序馍忽,比如可以在分類里編寫(xiě)此方法棒坏,用來(lái)判斷該分類是否已經(jīng)正確加載燕差。
? 想要執(zhí)行與類相關(guān)的初始化操作,還有個(gè)辦法坝冕,就是覆寫(xiě) +(void)initialize徒探;
? 該方法會(huì)在程序首次用該類之前調(diào)用,且只調(diào)用一次喂窟。其雖與load方法類似测暗,但卻有幾個(gè)非常重要的微妙區(qū)別:首先,它是“惰性調(diào)用的”磨澡,應(yīng)用程序無(wú)須把每個(gè)類的initialize方法都執(zhí)行一遍碗啄,這與load方法不同,對(duì)于load來(lái)說(shuō)稳摄,應(yīng)用程序必須阻塞等著所有的類的load都執(zhí)行完稚字,才能繼續(xù)。其次厦酬,運(yùn)行期系統(tǒng)在執(zhí)行該方法是胆描,是處于正常狀態(tài)的,運(yùn)行期系統(tǒng)也能確保initialize方法一定會(huì)在“線程安全的環(huán)境”中執(zhí)行仗阅,這就是說(shuō)昌讲,只有執(zhí)行initialize的那個(gè)線程可以操作類或類實(shí)例,其他線程都要先阻塞减噪,等著initialize執(zhí)行完短绸。最后车吹,initialize方法與其他消息一樣,如果某個(gè)類未實(shí)現(xiàn)它醋闭,而其超類實(shí)現(xiàn)了礼搁,那么就會(huì)運(yùn)行超類的實(shí)現(xiàn)代碼。
?
?