(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简单总结的更多相关文章

  1. Objective-C中NSInvocation的使用

    OC中调用方法某个对象的消息呦两种方式: #1. performanceSelector: withObject: #2. NSInvocation. 第一个PerformaceSelector比较常 ...

  2. IOS NSInvocation用法简介

    IOS NSInvocation用法简介 2012-10-25 19:59 来源:博客园 作者:csj007523 字号:T|T [摘要]在 iOS中可以直接调用某个对象的消息方式有两种,其中一种就是 ...

  3. NSInvocation的使用(转)

    转载自:http://www.cnblogs.com/pengyingh/articles/2359199.html http://blog.iosxcode4.com/?p=125 在 iOS中可以 ...

  4. ios NSMethodSignature and NSInvocation 消息转发

    1.首先获取消息转发时连个函数内部具体内容 MARK:这里是拿[@"xxxxx" length]调用拿来举例说明 (lldb) po signature <NSMethodS ...

  5. 关于 NSInvocation

    Invocation   调用的意思. 可想而知NSInvocation 是一个 方法调用 封装的类. 这体现了  面向对象的思想, 及一切皆对象.函数也不例外. 一般编程中,应该很少用到这个. 但是 ...

  6. 【造轮子】打造一个简单的万能Excel读写工具

    大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...

  7. Fabio 安装和简单使用

    Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...

  8. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  9. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

随机推荐

  1. 002-多线程-JUC集合-List-CopyOnWriteArrayList

    一.概述 CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略 ...

  2. opencv C++ mask_rcnn

    #include <fstream> #include <sstream> #include <iostream> #include <string.h> ...

  3. python基础----redis模块

    数据库 关系型数据 例如mysql,有表还有约束条件等 非关系型 k-v形式 memcache 存在内存中 redis 存在内存 mongodb 数据存在磁盘 import redis #string ...

  4. Caché,Cache数据库下载

    Caché数据库主要用于医疗领域,国内的开发人员比较少接触,使用环境相对封闭,前段时间刚才用到,下载也费了许多时间,特记录一下,帮助那些需要的人. 顺便说一下,TreeSoft数据库管理系统,目前支持 ...

  5. Ubuntu搭建Spring源码环境常见问题

    在一心想要学习Spring框架源码时,我们会遇到很多麻烦的问题.开始本文前,你只需要拥有一个装好IDEA的Ubuntu系统就可以愉快启程了.如果还没有IDEA,可以参考在Ubuntu上安装Intell ...

  6. power bi可视化--乘用车案例

  7. rabbitmq启动方式

    1.以应用方式启动 rabbitmq-server -detached 后台启动 Rabbitmq-server 直接启动,如果你关闭窗口或者需要在改窗口使用其他命令时应用就会停止  关闭:rabbi ...

  8. [CF991D]Bishwock_状压dp

    Bishwock 题目链接:http://codeforces.com/problemset/problem/991/D 数据范围:略. 题解: 一眼题. 首先,每个$L$最多只占用两列,而且行数特别 ...

  9. [转帖]sys.dm_exec_connections (Transact-SQL)

    sys.dm_exec_connections (Transact-SQL) https://docs.microsoft.com/en-us/sql/relational-databases/sys ...

  10. TP5.1框架中的模型关联

    一对一关联 hasOne('关联模型','外键','主键'); 关联模型(必须):关联的模型名或者类名 外键:默认的外键规则是当前模型名(不含命名空间,下同)+_id ,例如user_id 主键:当前 ...