method swizzing(hook 的一種)
因為runtime才開始進行方法實現(xiàn)確定的關(guān)系,我們可以在代碼中更改方法的實現(xiàn),這樣可以在不了解源代碼實現(xiàn)的基礎(chǔ)上自定義自己的實現(xiàn),由于牽涉到底層調(diào)用 此方法的副作用也很大 謹慎使用
hook 本來就是一種比較危險的行為,會造成一些難以預料的錯誤
method swizzing 就是在運行時期間 欺騙 runtime ,將 method 的implement 指向另一個地方,這樣代碼真正執(zhí)行時就會去另一個地方尋找,,,,
我們一般的是這樣
when we want to let the select1`s imp point to the imp2;we would use some runtime1``s method to acheive it.as the below:
有點類似 java 中的反射機制.系統(tǒng)給了我們很多接口讓我們可以去進行....
比如我們可以測試 在消息傳遞機制中synchronize的時間消耗是多少
我們要用到上次運行時中講到的一些方法
@interface NSUserDefaults (Timing)
@end
@implementation NSUserDefaults(Timing)
-(BOOL)swizzing_synchronize{
NSDate* startdate = [NSDate date];
BOOL returnvalue=[self swizzing_synchronize];
NSLog(@"Writing user defaults took %f seconds.", [[NSDate date] timeIntervalSinceDate:startdate]);
return returnvalue;
}
@end
這是我們改變后的方法的實現(xiàn) 可以看到里面是一個無限遞歸 --endless recursing..
+ (void)load
{
Method original, swizzled;
original = class_getInstanceMethod(self, @selector(synchronize));
swizzled = class_getInstanceMethod(self, @selector(swizzled_synchronize));
method_exchangeImplementations(original, swizzled);
}
調(diào)用 objc/runtiume.h 中的方法 改變了這兩個方法的實現(xiàn) 這樣,我們在使用的時候用的就不是原來的實現(xiàn)
類load方法會在任何類或分類加載的時候調(diào)用
![](http://darkdust.net/files/swizzling.png)