iOS利用runtime追蹤對象的每一個方法
我們會用到runtime替換方法來監聽某個方法的調用。例如,項目中每個Controller都直接繼承了UIViewController,但是現在想監聽每個Controller的viewDidAppear 和 viewDidDisappear,用法如下:
void qhd_exchangeInstanceMethod(Class class, SEL originalSelector, SEL newSelector) { Method originalMethod = class_getInstanceMethod(class, originalSelector); Method newMethod = class_getInstanceMethod(class, newSelector); if(class_addMethod(class, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { class_replaceMethod(class, newSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else {
method_exchangeImplementations(originalMethod, newMethod);
}
} @implementation UIViewController (Test)
+ (void)load {
qhd_exchangeInstanceMethod([self class], @selector(viewDidAppear:), @selector(qhd_viewDidAppear:)); qhd_exchangeInstanceMethod([self class], @selector(viewDidDisappear:), @selector(qhd_viewDidDisappear:)); }
- (void)qhd_viewDidAppear:(BOOL)animated { //[MobClick beginLogPageView:self.title];
[self qhd_viewDidAppear:animated];
}
- (void)qhd_viewDidDisappear:(BOOL)animated { //[MobClick endLogPageView:self.title];
[self qhd_viewDidDisappear:animated];
} @end
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
近產生了一個的想法:替換一個類的所有方法,每一個方法都打印一個log,看看調用順序是怎樣的,例如我想知道UIViewController在運行時到底都調用了哪些方法,包括私有方法。
思路是這樣的:
1.通過class_copyMethodList得出一個類的所有方法。
2.通過method_getTypeEncoding和method_copyReturnType得出方法的參數類型和返回值。
3.創建出SEL和IMP,通過class_addMethod動態添加新方法。
4.通過交換的思想,在新方法里通過NSInvocation來調用原方法。
難點在于,新方法里面怎么把方法的“實現”(即IMP)綁定上,并且在“實現”里調用原方法。在runtime的頭文件中Method的結構:
typedef struct objc_method *Method; struct objc_method
可以看到Method包含了是三個元素:一個SEL,一個char *,一個IMP。
SEL是方法名,char *是方法的類型,IMP就是實現的地址。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。