load:
-
+load
是一個(gè)類方法榜配,當(dāng)程序載入時(shí),在main函數(shù)執(zhí)行之前毒坛,帶有+load
方法類(Class)或者種類(Category)就會(huì)執(zhí)行+load
方法(每個(gè)+load
方法只執(zhí)行一次),比如:@interface Person : NSObject @end @implementation Person +(void)load { NSLog(@"Person is loaded"); } @end int main(int argc, const char *argv[]) { @autoreleasepool { // insert code here... NSLog(@"main is executed"); } return 0; } // Person is loaded // main is executed
我們可以看到,
Person
類中的+load
方法在main
執(zhí)行前就被調(diào)用了 -
當(dāng)父類和子類都實(shí)現(xiàn)
+load
方法時(shí)辨泳,父類和子類的+load
方法都會(huì)執(zhí)行(都只執(zhí)行一次),且父類的+load
方法執(zhí)行順序要優(yōu)先于子類玖院,比如:@interface Person : NSObject @end @interface Father : Person @end @implementation Person +(void)load { NSLog(@"Person is loaded"); } @end @implementation Father +(void)load { NSLog(@"Father is loaded"); } @end // Person is loaded // Father is loaded
我們可以看到
Fahter
是Person
的子類菠红,Person
執(zhí)行+load
方法后Father
才執(zhí)行+load
方法 -
當(dāng)子類未實(shí)現(xiàn)
+load
方法時(shí),不會(huì)調(diào)用父類+load
方法难菌,比如:@implementation Person +(void)load { NSLog(@"Person is loaded"); } @end @implementation Father //+(void)load { // NSLog(@"Father is loaded"); //} @end // Person is loaded
-
當(dāng)子類實(shí)現(xiàn)
+load
方法试溯,而父類沒有實(shí)現(xiàn)+load
方法時(shí),只調(diào)用子類的+load
方法:@implementation Person //+(void)load { // NSLog(@"Person is loaded"); //} @end @implementation Father +(void)load { NSLog(@"Father is loaded"); } @end // Father is loaded
-
類中的
+load
方法執(zhí)行順序要優(yōu)先于種類(Category)郊酒,種類中+load
方法的執(zhí)行順序和Compile Sources中出現(xiàn)的順序一致:@implementation Person +(void)load { NSLog(@"Person is loaded"); } @end @implementation Person (Category1) +(void)load { NSLog(@"Person Category1 is loaded"); } @end @implementation Person (Category2) +(void)load { NSLog(@"Person Category2 is loaded"); } @end @implementation Person (Category3) +(void)load { NSLog(@"Person Category3 is loaded"); } @end // Person is loaded // Person Category3 is loaded // Person Category1 is loaded // Person Category2 is loaded
可以看到
Person
類的+load
先于所有種類的執(zhí)行順序遇绞,而Compile Sources中Person
種類出現(xiàn)的順序是3,1燎窘,2摹闽,這對(duì)應(yīng)+load
執(zhí)行的順序 當(dāng)有多個(gè)不同的類的時(shí)候,每個(gè)類
+load
執(zhí)行順序與其在Compile Sources出現(xiàn)的順序一致+load
是線程安全的,要避免在+load
內(nèi)堵塞線程褐健。
initialize
在類收到第一條消息的時(shí)候調(diào)用付鹿,在main函數(shù)開始執(zhí)行后(因?yàn)轭惙椒ǖ恼{(diào)用在
main
中),可能某個(gè)類會(huì)一直不執(zhí)行+initialize
蚜迅,因?yàn)檫@個(gè)類可能只是被加載到程序中舵匾,而沒有被調(diào)用(收到消息),每個(gè)類只執(zhí)行+initialize
一次慢叨。-
父類的
+initialize
方法會(huì)比子類先執(zhí)行:@implementation Person +(void)initialize { NSLog(@"Person is initialized"); } @end @implementation Father +(void)initialize { NSLog(@"Father is initialized"); } @end int main(int argc, const char *argv[]) { @autoreleasepool { Father *father = [[Father alloc] init]; Person *person = [[Person alloc] init]; } return 0; } // Person is initialized // Father is initialized
-
當(dāng)子類未實(shí)現(xiàn)
+initialize
方法時(shí)纽匙,會(huì)調(diào)用父類+initialize
方法(這樣使得同一種+initialize
可能會(huì)被執(zhí)行多次,但這并不與每個(gè)類只執(zhí)行+initialize
一次相矛盾)拍谐。@implementation Person +(void)initialize { NSLog(@"Person is initialized"); } @end @implementation Father //+(void)initialize { // NSLog(@"Father is initialized"); //} @end int main(int argc, const char *argv[]) { @autoreleasepool { Father *father = [[Father alloc] init]; } return 0; } // Person is initialized // Person is initialized
-
當(dāng)有多個(gè)Category都實(shí)現(xiàn)了
+initialize
方法時(shí)烛缔,會(huì)覆蓋類中的方法,+initialize
方法只執(zhí)行一次(會(huì)執(zhí)行Compile Sources 列表中最后一個(gè)Category 的+initialize
方法)@implementation Person +(void)initialize { NSLog(@"Person is initialized"); } @end @implementation Person (Category1) +(void)initialize { NSLog(@"Person Category1 is initialized"); } @end @implementation Person (Category2) +(void)initialize { NSLog(@"Person Category2 is initialized"); } @end @implementation Person (Category3) +(void)initialize { NSLog(@"Person Category3 is initialized"); } @end // Person Category2 is initialized
Compile Sources中Catergory出現(xiàn)的順序是3轩拨,2践瓷,1,
+initialize
執(zhí)行一次亡蓉,執(zhí)行的是最后一個(gè)(1)晕翠。 +initiallize
是線程安全的,要避免在+initiallize
內(nèi)堵塞線程。
總結(jié)
方法 | +load |
+initialize |
---|---|---|
執(zhí)行時(shí)間 | 類載入程序時(shí) | 類第一次接受消息時(shí) |
執(zhí)行次數(shù) | 每個(gè)+load 方法只執(zhí)行一次淋肾,不會(huì)出現(xiàn)重復(fù)執(zhí)行 |
每個(gè)類的+initialize 方法只執(zhí)行一次硫麻,可能會(huì)重復(fù)執(zhí)行 |
父類是否優(yōu)先于子類執(zhí)行 | 是 | 是 |
子類不實(shí)現(xiàn)時(shí),是否調(diào)用父類 | 否 | 是(導(dǎo)致父類+initialize 方法執(zhí)行次數(shù)+1) |
子類是否覆蓋父類 | 否 | 是 |
Category是否覆蓋類 | 否 | 是 |
類的執(zhí)行是否優(yōu)先于Category | 是 | 是(因?yàn)橹粓?zhí)行一次) |
多個(gè)Category執(zhí)行次數(shù) | Category的數(shù)量 | 和類一起樊卓,總共一次 |
多個(gè)Category執(zhí)行順序 | Compile Sources中文件出現(xiàn)的順序 | Compile Sources中文件出現(xiàn)順序的最后一個(gè) |