+(void)load
{
//確保線程安全原子操作,
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class aClass = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(zc_viewWillAppear:);
// 通過(guò)class_getInstanceMethod()函數(shù)從當(dāng)前對(duì)象中的method list獲取method結(jié)構(gòu)體,如果是類方法就使用class_getClassMethod()函數(shù)獲取。
Method originalMethod = class_getInstanceMethod(aClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector);
// When swizzling a class method, use the following:
// Class aClass = object_getClass((id)self);
// ...
// Method originalMethod = class_getClassMethod(aClass, originalSelector);
// Method swizzledMethod = class_getClassMethod(aClass, swizzledSelector);
//添加方法
BOOL didAddMethod =
class_addMethod(aClass,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
/** * 我們?cè)谶@里使用class_addMethod()函數(shù)對(duì)Method Swizzling做了一層驗(yàn)證,如果self沒有實(shí)現(xiàn)被交換的方法,會(huì)導(dǎo)致失敗。
* 而且self沒有交換的方法實(shí)現(xiàn),但是父類有這個(gè)方法,這樣就會(huì)調(diào)用父類的方法,結(jié)果就不是我們想要的結(jié)果了。
* 所以我們?cè)谶@里通過(guò)class_addMethod()的驗(yàn)證,如果self實(shí)現(xiàn)了這個(gè)方法,class_addMethod()函數(shù)將會(huì)返回NO,我們就可以對(duì)其進(jìn)行交換了。 */
//didAddMethod返回NO,說(shuō)明已實(shí)現(xiàn)這個(gè)方法,不需要添加,然后我們交換方法即可,否則則用原方法代理我們的swizzledMethod
if (didAddMethod) {
class_replaceMethod(aClass,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)zc_viewWillAppear:(BOOL)animation
{
NSString *str = [NSString stringWithFormat:@"%@", self.class];
// 我們?cè)谶@里加一個(gè)判斷,將系統(tǒng)的UIViewController的對(duì)象剔除掉
if(![str containsString:@"UI"]){
NSLog(@"統(tǒng)計(jì)打點(diǎn) : %@", self.class);
}
NSLog(@"zc_viewwillAppear");
Method Swizzling
的實(shí)現(xiàn)原理可以理解為”方法互換“。
假設(shè)我們將A和B兩個(gè)方法進(jìn)行互換,向A方法發(fā)送消息時(shí)執(zhí)行的卻是B方法,向B方法發(fā)送消息時(shí)執(zhí)行的是A方法。
[self zc_viewWillAppear:animation];
}
Method Swizzling
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 下午接到一個(gè)有趣的問(wèn)題: 看到這個(gè)問(wèn)題的第一想法就是利用runtime的方法交換,通過(guò)自己的方法替換系統(tǒng)方法,在自...
- 該文章屬于劉小壯原創(chuàng),轉(zhuǎn)載請(qǐng)注明:劉小壯[http://www.itdecent.cn/u/2de707c93d...
- 前言 記得《大話西游2》中有這么個(gè)橋段,紫霞仙子和豬八戒中招移魂幻影大法后靈魂互換,當(dāng)時(shí)看的也是淚流滿面。。而Me...
- 問(wèn)題 熟悉iOS開發(fā)的都知道,如果我們往Array或Dictionary中插入nil,應(yīng)用就會(huì)崩潰。如有下面客戶端...
- 在 Runtime 改變selector所對(duì)應(yīng)的 imp 來(lái)達(dá)到讓原有 method 實(shí)現(xiàn)其他功能的目的 我們可以...