有没有使用过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 欢迎大家的阅读和赞扬、谢谢!