主類和分類
一. 需要解決的問題
- 主類和分類中普通方法的調用順序?
- 同一個主類的兩個分類中的同名方法調用順序?
- 分類中+load方法的調用順序?
- 分類中+initialize 方法的調用順序?
二. 測試環(huán)境搭建
-
創(chuàng)建下面這些測試用的類
這里寫圖片描述 加入一個pch文件方便打印
#ifdef DEBUG
#define LGLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__);
#else
#define LGLog(...)
#endif
---------------------
主要內(nèi)容
1. 主類,子類和分類中的+load方法的加載
- 我們在主類和各分類中重寫+load方法
//Person
+ (void)load{
LGLog();
}
//-------------
//Son
+ (void)load{
LGLog();
}
//-------------
Person+A
+ (void)load{
LGLog();
}
//-------------
Person+B
+ (void)load{
LGLog();
}
//-------------
Person+C
+ (void)load{
LGLog();
}
---------------------
-
打印輸出
這里寫圖片描述 -
調整分類的編譯順序在打印
這里寫圖片描述
2. 結論
- +load方法的調用是在main() 函數(shù)之前,并且不需要主動調用,就是說程序啟動會把所有的文件加載
- 主類和分類的都會加載調用+load方法
- 主類與分類的加載順序是:主類優(yōu)先于分類加載,無關編譯順序
- 分類間的加載順序取決于編譯的順序:編譯在前則先加載,編譯在后則后加載
- 規(guī)則是父類優(yōu)先于子類, 子類優(yōu)先于分類(父類>子類>分類)
1. 探究主類和分類的普通同名方法調用順序
- 我們在主類中加入普通的類方法(+commonClsMethod)和實例方法(-commonInstanceMethod)
- 在分類中也重寫這兩個方法
+ (void)commonClsMethod{
LGLog();
}
- (void)commonInstanceMethod{
LGLog();
}
-
正常結果
這里寫圖片描述 -
分類文件警告
這里寫圖片描述
結論
- 普通的方法中, 分類同名方法會覆蓋主類的方法
- 多個分類中的同名方法會只執(zhí)行一個,即后編譯的分類里面的方法會覆蓋所有前面的同名方法(可以通過調換編譯順序來獲得這個結論)
- 分類中的方法名和主類方法名一樣會報警告,大概就是說分類中實現(xiàn)的方法主類已經(jīng)實現(xiàn)了
- 可以把聲明寫在主類, 實現(xiàn)寫在分類,這樣也能調用到分類里面的代碼
- 同樣可以把聲明和實現(xiàn)寫在不同的分類文件中,還是能找到的, 不過主類要相同
探究+ initialize方法的調用
- 調用子類的+ (void)initialize方法
[[Son new] commonInstanceMethod];
這里寫圖片描述
結論
- 當?shù)谝淮斡玫筋惖臅r候, 如果重寫了+ initialize方法,會去調用
- 當調用子類的+ initialize方法時候, 先調用父類的,如果父類有分類, 那么分類的+ initialize會覆蓋掉父類的, 和普通方法差不多
- 父類的+ initialize不一定會調用, 因為分類可能重寫了它
- 普通方法的優(yōu)先級:分類>子類>父類
總結
- 普通方法的優(yōu)先級: 分類> 子類 > 父類, 優(yōu)先級高的同名方法覆蓋優(yōu)先級低的
- +load方法的優(yōu)先級: 父類> 子類> 分類
- +load方法是在main() 函數(shù)之前調用,所有的類文件都會加載,包括分類
- +load方法不會被覆蓋
- 同一主類的不同分類中的普通同名方法調用, 取決于編譯的順序, 后編譯的文件中的同名方法會覆蓋前面所有的,包括主類. +load方法的順序也取決于編譯順序, 但是不會覆蓋
- 分類中的方法名和主類方法名一樣會報警告, 不會報錯
- 聲明和實現(xiàn)可以寫在不同的分類中, 依然能找到實現(xiàn)
- 當?shù)谝淮斡玫筋惖臅r候, 如果重寫了+ initialize方法,會去調用
- 當調用子類的+ initialize方法時候, 先調用父類的,如果父類有分類, 那么分類的+ initialize會覆蓋掉父類的, 和普通方法差不多
- 父類的+ initialize不一定會調用, 因為有可能父類的分類重寫了它
demo
- https://github.com/LGLee/categoryDemo
- 下載下來通過注釋或者其他的方式可以驗證或者添加其他的方法驗證,這只是一個簡單的探究