Cocoa触发方法调用的几种方法
2016-01-20 18:00
381 查看
每日更新关注:http://weibo.com/hanjunqiang
新浪微博
1.SEL触发
SEL就是selector的缩写,它表示Cocoa中的方法选择器,不明白?那请仔细了解Objective_C的运行时机制与Cocoa底层思想。SEL theSelector = @selector(methodWithInt:andInt:);
看了上面代码这下你明白了什么是SEL了吧,平时我们开发当中经常用到的。
有了SEL这样就可以触发方法调用了,
[self performSelector:theSelector] [self performSelector:@selector(methodWithInt:andInt:)];
上面两句代码是同一个道理。
2. IMP触发
IMP其实就是一个函数指针的概念,就可以这么简单理解。IMP theImplementation = [self methodForSelector:theSelector];
上面这句代码就是获取methodWithInt:andInt:这个方法的地址。
有了这个函数指针后,我们就可以触发方法:
theImplementation(self, theSelector, 30, 5);
第一个是对象,第二个SEL, 后面的传入的参数。
每日更新关注:http://weibo.com/hanjunqiang
新浪微博
3. objc_msgSend方法
这是Objc运行时的一个C方法,我们先看一个示列:objc_msgSend(self, @selector(fly)); [self fly];
4. NSInvocation
NSInvocation相比上面几种方法,可以动态决定传入的参数个数。有了它,我们就可以实现…这样的变参API封装。说得有点抽像,看代码更清楚:
假如我们实现了一个两个数相加的方法,
-(void)addNSNumber:(NSNumber *)first withNumber:(NSNumber *)second
我们可以用下面的方法来触发这个方法,并获取返回值。
NSNumber *arg1 = [NSNumber numberWithDouble:15.0]; NSNumber *arg2 = [NSNumber numberWithDouble:13.0]; SEL selector = @selector(addNSNumber:withNumber:); NSMethodSignature *sig = [self methodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; [invocation setTarget:self]; [invocation setSelector:selector]; [invocation setArgument:(void *)&arg1 atIndex:2]; [invocation setArgument:(void *)&arg2 atIndex:3]; [invocation invoke]; if ([sig methodReturnLength]) { [invocation getReturnValue:&retval]; return retval; } return nil; }
代码很容易理解,我也不多做解释,有不明白的请留言。
每日更新关注:http://weibo.com/hanjunqiang
新浪微博
下面是变参封装, 写了两个NSObject的Extension(Category):
+ (NSInvocation *)createInvocationOnTarget:(id)target selector:(SEL)selector { return [NSObject createInvocationOnTarget:target selector:selector withArguments:nil]; } + (NSInvocation *)createInvocationOnTarget:(id)target selector:(SEL)selector withArguments:(id)arg1, ... { NSMethodSignature *sig = [target methodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; [invocation setTarget:target]; [invocation setSelector:selector]; if(arg1) { va_list args; va_start(args, arg1); [invocation setArgument:(void *)&arg1 atIndex:2]; id obj; int ct = 3; while( obj = va_arg(args, id) ) { NSLog(@"%@", obj); [invocation setArgument:(void *)&obj atIndex:ct]; ct++; } va_end(args); } return invocation; } [/code] |
NSInvocation *invocation = [NSObject createInvocationOnTarget:mathInstance selector:selector withArguments: arg1, arg2, nil]; [invocation invoke]; [invocation getReturnValue:&retval]; return retval; [/code] |
新浪微博
相关文章推荐
- Cocoa触发方法调用的几种方法
- iOS 滑动性能优化
- 三分
- android JSON数据格式 解析
- 让系统照片选择器的导航栏变蓝的代码
- 如何只花1小时,搞定全天工作
- Maven3路程(三)用Maven创建第一个web项目(1)
- Ajax 文件上传
- c#程序内存分配
- eclipse svn插件安装
- Python程序的执行原理
- moo 7 Servlet init() doget() dopost() service()方法之间的区别及应用/GenericServlet、Servlet、HttpServlet借口之间的关系
- 新建WebService供JQuery调用及用js判断是否要调用服务器的submit
- Android开发之--自定义控件学习
- Android开发入门Hello World
- 1.2. Java基础知识 1.2.1. 阅读源代码
- APPCAN学习笔记001---app高速开发AppCan.cn平台概述
- js中继承的方法总结(apply,call,prototype)
- 转:RabbitMQ基础知识
- mongo db ubuntu 12.04安装