Method Swizzling
//
// UIViewController+Tracking.m
// tesssss
//
// Created by iOS on 23/11/17.
// Copyright ? 2017年 iOS. All rights reserved.
//
#import "UIViewController+Tracking.h"
#import <objc/runtime.h>
@implementation UIViewController (Tracking)
// 放在load方法中,當類被加載之后就執行以下方法。
+ (void)load {
// 防止手動調用 class 方法,保證替換方法只執行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(ICE_viewWillAppear:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
/*
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,
const char * _Nullable types)
* Class cls cls 參數表示需要添加新方法的類。
* SEL name name 參數表示 selector 的方法名稱,可以根據喜好自己進行命名。
* IMP imp imp 即 implementation ,表示由編譯器生成的、指向實現方法的指針。也就是說,這個指針指向的方法就是我們要添加的方法。
* const char *types 最后一個參數 *types 表示我們要添加的方法的返回值和參數。
如果發現方法已經存在,會失敗返回,也可以用來做檢查是否已經添加過方法了,我們這里是為了避免源方法沒有實現的情況;
如果方法沒有存在,我們則先嘗試添加被替換的方法的實現
*/
BOOL didAddMethod = class_addMethod(
class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod)
);
/*
判斷class_addMethod是否已經添加成功了
YES 則說明被替換方法不存在.也就是被替換的方法沒有被實現,我們需要先把這個方法實現,然后再執行我們想要的效果,用我們自定義的方法去替換被替換的方法. 這里使用到的是class_replaceMethod這個方法. class_replaceMethod本身會嘗試調用class_addMethod和method_setImplementation,所以直接調用class_replaceMethod就可以了)
NO 則說明被替換方法已經存在.直接將兩個方法的實現交換即
*/
if (didAddMethod) {
class_replaceMethod(
class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod)
);
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)ICE_viewWillAppear:(BOOL)animated {
[self ICE_viewWillAppear:animated];
NSLog(@"ICEviewWillAppear:%@",self);
}
@end
//如果替換的是類方法
Class classB = Object_getClass ((id) self);
SEL originalSelector = @selector (想要替換的類方法);
SEL swizzledSelector = @selector (替換的新方法名) ;
Method originalMethod = class_getClassMethod (classB, originalSelector);
Method swizzlingMethod = class_getClassMethod (classB, swizzledSelector);
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。