1.正常的方法交換代碼
+?(void)load?{
[superload];
//?通過class_getInstanceMethod()函數(shù)從當(dāng)前對象中的method?list獲取method結(jié)構(gòu)體颤练,如果是類方法就使用class_getClassMethod()函數(shù)獲取。
Method?fromMethod?=?class_getInstanceMethod([self?class],?@selector(viewDidLoad));
Method?toMethod?=?class_getInstanceMethod([self?class],?@selector(swizzlingViewDidLoad));
method_exchangeImplementations(fromMethod,?toMethod);
}
2.NSArray嗦玖,NSMutableArray,NSDictionary,NSMutableDictionary時
+?(void)load?{
[superload];
Method?fromMethod?=?class_getInstanceMethod(objc_getClass("__NSArrayI"),?@selector(objectAtIndex:));
Method?toMethod?=?class_getInstanceMethod(objc_getClass("__NSArrayI"),?@selector(lxz_objectAtIndex:));
method_exchangeImplementations(fromMethod,?toMethod);
}
3.上面兩個方法對比可知,參數(shù)發(fā)生了變化,原因:
這是因為Method Swizzling對NSArray這些的類簇是不起作用的匾乓。因為這些類簇類,其實是一種抽象工廠的設(shè)計模式拼缝。抽象工廠內(nèi)部有很多其它繼承自當(dāng)前類的子類,抽象工廠類會根據(jù)不同情況咧七,創(chuàng)建不同的抽象對象來進(jìn)行使用。例如我們調(diào)用NSArray的objectAtIndex:方法耻涛,這個類會在方法內(nèi)部判斷,內(nèi)部創(chuàng)建不同抽象類進(jìn)行操作抹缕。
所以也就是我們對NSArray類進(jìn)行操作其實只是對父類進(jìn)行了操作,在NSArray內(nèi)部會創(chuàng)建其他子類來執(zhí)行操作卓研,真正執(zhí)行操作的并不是NSArray自身,所以我們應(yīng)該對其“真身”進(jìn)行操作奏赘。
下面我們列舉一些常用的類簇的“真身”: