有沒有使用過performSelector,
使用過
何時使用?
動態添加方法的時候使用過
怎麼動態添加方法?
使用runtime
爲何要動態添加方法?
OC都是懶加載機制,只要一個方法實現了,就會立刻添加到方法列表上.方法中有不少映射關係,這無形中就會消耗了內存
好比一個app:有免費版、收費版
好比:QQ、微博、直播等等應用,都有會員機制,這樣咱們能夠動態添加方法1ios
Runtime (動態添加方法):xcode
若是咱們建立一個Person類,而後在viewDidLoad中建立該對象,咱們使用performSelector去調用一個Person類中沒有的方法,結果系統報錯找不到方法:app
Person *p = [[Person alloc]init]; // 執行某個方法 [p performSelector:@selector(eat)];
#import <Foundation/Foundation.h> @interface Person : NSObject @end #import "Person.h" #import <objc/message.h> @implementation Person @end
這時候咱們能夠動態去添加方法:ide
// 任何方法默認都有兩個隱式參數,self,_cmd // 做用:動態添加方法、或者處理一些未實現的方法 // 何時調用?只要一個對象調用了一個未實現的方法,就會調用這個方法來進行處理 + (BOOL)resolveInstanceMethod:(SEL)sel { //NSLog(@"%@",NSStringFromSelector(sel)); //[NSStringFromSelector(sel) isEqualToString:@"eat"] if (sel == NSSelectorFromString(@"eat")) { // class:第一個參數:給那個類添加方法 // SEL:添加哪一個方法 // IMP:implementation:方法=>函數=>函數的入口=>函數名 // type:方法的類型 class_addMethod(self, sel, (IMP)funcA, "v@:"); return YES; } return [super resolveInstanceMethod:sel]; }
2.主要是這個方法的參數咱們要掌握:class_addMethod(self, sel, (IMP)funcA, "v@:");函數
查看參數文檔地址:xcode-->window-->Documentation and API Reference-->展開ios9.3-->Languages & Utilities-->Objective-C-->Guides-->Objective-C Runtime Programming Guide-->Dynamic Method Resolution + Type Encodingsui
Runtime中文文檔地址連接: http://blog.csdn.net/liangliang103377/article/details/39007683 spa
// 聲明一個函數 void funcA(id self,SEL _cmd) { NSLog(@"吃東西"); }
若是咱們是動態建立一個帶有參數的方法:.net
#import "Person.h" #import <objc/message.h> @implementation Person // 聲明一個函數 void funcA(id self,SEL _cmd,NSNumber *metre) { NSLog(@"跑了%@米",metre); } + (BOOL)resolveInstanceMethod:(SEL)sel { //NSLog(@"%@",NSStringFromSelector(sel)); //[NSStringFromSelector(sel) isEqualToString:@"eat"] if (sel == NSSelectorFromString(@"run:")) { // class:第一個參數:給那個類添加方法 // SEL:添加哪一個方法 // IMP:implementation:方法=>函數=>函數的入口=>函數名 // type:方法的類型 class_addMethod(self, sel, (IMP)funcA, "v@:@"); return YES; } return [super resolveInstanceMethod:sel]; } @end
方法的調用:code
- (void)viewDidLoad { [super viewDidLoad]; // _cmd:當前方法方法編號 NSLog(@"%@",NSStringFromSelector(_cmd)); Person *p = [[Person alloc]init]; // 執行某個方法 [p performSelector:@selector(run:) withObject:@100]; }
最後打印:跑了100米orm
知識點:
- 1:任何方法默認都有兩個隱式參數:self、_cmd
- 2:_cmd:當前方法方法編號
- 在ViewDidLoad中打印該參數:
- NSLog(@"%@",NSStringFromSelector(_cmd));
3:+ (BOOL)resolveInstanceMethod:(SEL)sel ?做用?何時調用?
>何時調用?只要一個對象調用了一個未實現的方法,就會調用這個方法來進行處理
>做用?動態添加方法、或者處理一些未實現的方法
意見反饋郵件:1415429879@qq.com 歡迎大家的閱讀和讚揚、謝謝!