在進入一個新公司時候岩臣,接觸新的項目溜嗜。在修改一些界面,而不知這個頁面具體是工程中哪個類實現(xiàn)架谎。而必須一個個類頁面慢慢的尋找炸宵。其實我們可以直接使用RunTime的方法攔截和替換方法來監(jiān)聽頁面WillAppear
方法的實現(xiàn),打印出此類的文件名狐树,而不影響類中原有的方法實現(xiàn)焙压。
創(chuàng)建一個UIViewController
的分類,實現(xiàn)代碼后抑钟,直接丟入想要的查看的APP項目中涯曲,無需#import操作,方便快捷在塔。
#import "UIViewController+LogClassName.h"
#import <objc/runtime.h>
@implementation UIViewController (LogClassName)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class targetClass = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(swizzled_viewWillAppear:);
swizzleMethod(targetClass, originalSelector, swizzledSelector);
});
}
void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
IMP swizzledImp = method_getImplementation(swizzledMethod);
char *swizzledTypes = (char *)method_getTypeEncoding(swizzledMethod);
IMP originalImp = method_getImplementation(originalMethod);
char *originalTypes = (char *)method_getTypeEncoding(originalMethod);
BOOL success = class_addMethod(class, originalSelector, swizzledImp, swizzledTypes);
if (success) {
class_replaceMethod(class, swizzledSelector, originalImp, originalTypes);
}else {
// 添加失敗幻件,表明已經(jīng)有這個方法,直接交換
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
- (void)swizzled_viewWillAppear:(BOOL)animation {
[self swizzled_viewWillAppear:animation];
NSLog(@"\n--------------------------------\n\n<----------------- 此類的名字是( %@ ) ----------------->\n\n--------------------------------\n", NSStringFromClass([self class]));
}
@end
+(void)load{}
方法只要文件存在項目中蛔溃,方法會在加載類的時候就被調(diào)用绰沥,也就是 ios 應用啟動的時候篱蝇,就會加載所有的類,就會調(diào)用每個類的 + load 方法徽曲。
dispatch_once
保證方法替換只執(zhí)行一次
class_addMethod:
如果發(fā)現(xiàn)方法已經(jīng)存在零截,會失敗返回,也可以用來做檢查用,我們這里是為了避免源方法沒有實現(xiàn)的情況;如果方法沒有存在,我們則先嘗試添加被替換的方法的實現(xiàn):如果返回成功秃臣,說明被替換方法沒有存在涧衙。被替換的方法沒有被實現(xiàn),我們需要先把這個方法實現(xiàn)奥此,然后再執(zhí)行我們想要的效果弧哎,用我們自定義的方法去替換被替換的方法。
如果返回失斨苫ⅰ:則說明被替換方法已經(jīng)存在.直接將兩個方法的實現(xiàn)交換即
class_replaceMethod
這個方法.class_replaceMethod
本身會嘗試調(diào)用class_addMethod
和method_setImplementation
撤嫩,所以直接調(diào)用class_replaceMethod
就可以了)