NSInvocation简单总结
(1)用法
NSInvocation是调用函数的另一种方式,它将调用者,函数名,参数封装到一个对象,然后通过一个invoke函数来执行被调用的函数,其思想就是命令者模式,将请求封装成对象。
例如,有这样一个类:
@implementation CA
-(int)AddA:(int)a andB:(int)b
{
return a + b;
}
@end
一般调用函数的方式是:
CA *ca = [CA new];
int result = [ca AddA:2 andB:3];
或者用performSelector,但是后者只能有一个参数,所以对于有多个参数的情况,就可以用NSInvocation来调用。
示例代码:
CA *ca = [CA new];
NSMethodSignature *sig= [[CA class] instanceMethodSignatureForSelector:@selector(AddA:andB:)]; //根据selector得到一个签名对象
NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:sig];//根据该签名对象创建一个NSInvocation对象
invocation.target = ca;//指定调用函数的对象
invocation.selector = @selector(AddA:andB:);//指定要调用的函数名
int a = 20;
int b = 30;
[invocation setArgument:&a atIndex:2];//指定参数,以指针方式,并且第一个参数的起始index是2,因为index为1,2的分别是self和selector
[invocation setArgument:&b atIndex:3];
[invocation retainArguments];//因为NSInvocation不会自己去retain参数,因此需要用户去retain,当然本例中其实没必要
[invocation invoke];
//获取返回值的过程略有点复杂,需要根据起类型长度分配空间,然后转为对象
//如果是int,BOOL等简单类型,返回的对象是NSNumber
//如果是其他类型的对象,返回的对象是NSValue
//判断返回值类型,用strcmp(returnType, @encode(NSInteger))
const char *returnType = sig.methodReturnType;
id returnValue;
NSUInteger length = [sig methodReturnLength];
void *buffer = (void *)malloc(length);
[invocation getReturnValue:buffer];
returnValue = [NSNumber numberWithInteger:*((NSInteger*)buffer)];//int的情况
//returnValue = [NSNumber numberWithBool:*((BOOL*)buffer)]; //bool 的情况
//returnValue = [NSValue valueWithBytes:buffer objCType:returnType];// 其他类型的情况
int result = [returnValue intValue];
NSLog(@"result=%d",result);
(2) 用到NSInvocation的一些场合
[NSTimer scheduledTimerWithTimeInterval:0.1 invocation:invocation repeats:YES]
NSInvocationOperation //它是NSOperation的派生类,用NSInvoation来初始化
(void)forwardInvocation:(NSInvocation *)anInvocation
这个函数与forwardTargetWithSelector类似,当某个对象收到一个selector消息,但该对象没有实现该selector,且实现forwardInvocation,那么系统会构造一个NSInvocation对象,并调用forwardInvocation,这样在函数里面,用户就可以用[invocation invokeWithTarget:friend];来让另一个对象来执行这个selector.
要实现这个函数,还必须实现methodSignatureForSelector,因为这个anInvocation是系统构造的,构造这个对象需要有签名对象,这个对象必须由用户提供。所以这个函数用起来比forwardingTargetForSelector麻烦
另外,由于使用forwardInvocation可以使得一个对象将它没有实现的方法转发给其他对象,因此可以变相的实现多继承。
参考链接:http://www.cnblogs.com/pengyingh/articles/2359199.html
NSInvocation简单总结的更多相关文章
- Objective-C中NSInvocation的使用
OC中调用方法某个对象的消息呦两种方式: #1. performanceSelector: withObject: #2. NSInvocation. 第一个PerformaceSelector比较常 ...
- IOS NSInvocation用法简介
IOS NSInvocation用法简介 2012-10-25 19:59 来源:博客园 作者:csj007523 字号:T|T [摘要]在 iOS中可以直接调用某个对象的消息方式有两种,其中一种就是 ...
- NSInvocation的使用(转)
转载自:http://www.cnblogs.com/pengyingh/articles/2359199.html http://blog.iosxcode4.com/?p=125 在 iOS中可以 ...
- ios NSMethodSignature and NSInvocation 消息转发
1.首先获取消息转发时连个函数内部具体内容 MARK:这里是拿[@"xxxxx" length]调用拿来举例说明 (lldb) po signature <NSMethodS ...
- 关于 NSInvocation
Invocation 调用的意思. 可想而知NSInvocation 是一个 方法调用 封装的类. 这体现了 面向对象的思想, 及一切皆对象.函数也不例外. 一般编程中,应该很少用到这个. 但是 ...
- 【造轮子】打造一个简单的万能Excel读写工具
大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...
- Fabio 安装和简单使用
Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
随机推荐
- 关于对多层嵌套的json字符串取目标值的问题
import java.util.HashMap;import java.util.Iterator;import java.util.Map;import net.sf.json.JSONObjec ...
- PAT 甲级 1020 Tree Traversals (25 分)(二叉树已知后序和中序建树求层序)
1020 Tree Traversals (25 分) Suppose that all the keys in a binary tree are distinct positive integ ...
- Python排序算法之选择排序定义与用法示例
Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...
- ElasticSearch——分页查询
前言 ElasticSearch实现分页查询,有3种方式,他们在数据查询中各自占据着不同的优势,因此在搜索引擎的数据分页过程中,如何更好地利用各自的优势来进行数据查询是一个非常重要的过程. 传统分页( ...
- Spring Aop(七)——基于XML配置的Spring Aop
转发:https://www.iteye.com/blog/elim-2396043 7 基于XML配置的Spring AOP 基于XML配置的Spring AOP需要引入AOP配置的Schema,然 ...
- Docker Java程序镜像制作
Docker Java程序镜像制作 制作前的准备 jre:不需要完整的jdk,jre即可,到Oracle进行下载即可,下载链接,根据自己的情况进行选择,这里选择jre-8u221-linux-x64. ...
- 文件夹中含有子文件夹,修改子文件夹中的图像存储格式(python实现)
文件夹中含有子文件夹,修改子文件夹中的图像存储格式,把png图像改为jpg图像,python代码如下: import os import cv2 filePath = 'C:\\Users\\admi ...
- springmvc项目 logback.xml配置 logstash日志收集
配置logback,需要一个转接的Appender,可以通过Maven依赖加到项目中: <dependency> <groupId>com.cwbase</groupId ...
- 关于Python Web框架——Tornado
关于Tornado的入门看这篇文章,写的非常好: https://zhuanlan.zhihu.com/p/37382503 Tornado 是一个Python web框架和异步网络库,使用非阻塞网络 ...
- Linear regression with one variable - Model representation
摘要: 本文是吴恩达 (Andrew Ng)老师<机器学习>课程,第二章<单变量线性回归>中第6课时<模型概述>的视频原文字幕.为本人在视频学习过程中逐字逐句记录下 ...