转载自:http://www.cnblogs.com/pengyingh/articles/2359199.html

http://blog.iosxcode4.com/?p=125

在 iOS中可以直接调用 某个对象的消息 方式有2种

一种是performSelector:withObject:

再一种就是NSInvocation

第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那就需要做些额外工作才能搞定。那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作

NSInvocation可以处理参数、返回值。会java的人都知道反射操作,其实NSInvocation就相当于反射操作。

下面这个例子描述了如何使用NSInvocation,以下例子中如果要正常运行,需要把不存在的类进行正确填写。

//方法签名类,需要被调用消息所属的类AsynInvoke ,被调用的消息invokeMethod:

NSMethodSignature *sig= [[AsynInvoke class] instanceMethodSignatureForSelector:@selector(invokeMethod:)];

//根据方法签名创建一个NSInvocation

NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:sig];

//设置调用者也就是AsynInvoked的实例对象,在这里我用self替代

[invocation setTarget:self];

//设置被调用的消息

[invocation setSelector:@selector(invokeMethod:)];

//如果此消息有参数需要传入,那么就需要按照如下方法进行参数设置,需要注意的是,atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target 和selector占用

NSInteger num=10;

[invocation setArgument:&num atIndex:2];

//retain 所有参数,防止参数被释放dealloc

[invocation retainArguments];

//消息调用

[invocation invoke];

//如果调用的消息有返回值,那么可进行以下处理

//获得返回值类型

const char *returnType = sig.methodReturnType;

//声明返回值变量

id returnValue;

//如果没有返回值,也就是消息声明为void,那么returnValue=nil

if( !strcmp(returnType, @encode(void)) ){

returnValue =  nil;

}

//如果返回值为对象,那么为变量赋值

else if( !strcmp(returnType, @encode(id)) ){

[invocation getReturnValue:&returnValue];

}

else{

//如果返回值为普通类型NSInteger  BOOL

//返回值长度

NSUInteger length = [sig methodReturnLength];

//根据长度申请内存

void *buffer = (void *)malloc(length);

//为变量赋值

[invocation getReturnValue:buffer];

if( !strcmp(returnType, @encode(BOOL)) ) {

returnValue = [NSNumber numberWithBool:*((BOOL*)buffer)];

}

else if( !strcmp(returnType, @encode(NSInteger)) ){

returnValue = [NSNumber numberWithInteger:*((NSInteger*)buffer)];

}

returnValue = [NSValue valueWithBytes:buffer objCType:returnType];

}

NSInvocation调用

CurrentDate.h


#import <Foundation/Foundation.h>

@interface CurrentDate : NSObject {

}
- (NSString *) stringForDate: (NSDate *)date 
usingFormatter: (NSDateFormatter *)formatter; @end
复制代码

CurrentDate.m


#import "CurrentDate.h"

@implementation CurrentDate

- (NSString *) stringForDate: (NSDate *)date 
usingFormatter: (NSDateFormatter *)formatter
{
return [formatter stringFromDate: date];
} @end
复制代码

main.m


#import <Foundation/Foundation.h>
#import "CurrentDate.h" //参考:http://theocacao.com/document.page/264
int main (int argc, constchar* argv[])
{ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //原始调用
NSDateFormatter * dateFormat = [[NSDateFormatter alloc] 
initWithDateFormat:@"%b %d %Y" 
allowNaturalLanguage: NO];
CurrentDate * currentDateClassObject = [[CurrentDate alloc] init];
NSString * currentDate = [currentDateClassObject 
stringForDate: [NSDate date] 
usingFormatter: dateFormat];
NSLog(@"currentDate: %@", currentDate); //NSInvocation调用
SEL mySelector = @selector(stringForDate:usingFormatter:);
NSMethodSignature * sig = [[currentDateClassObject class] 
instanceMethodSignatureForSelector: mySelector]; NSInvocation * myInvocation = [NSInvocation invocationWithMethodSignature: sig];
[myInvocation setTarget: currentDateClassObject];
[myInvocation setSelector: mySelector]; NSDate * myDate = [NSDate date];
[myInvocation setArgument: &myDate atIndex: 2]; NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle: NSDateFormatterMediumStyle]; 
[myInvocation setArgument: &dateFormatter atIndex: 3]; NSString * result = nil; 
[myInvocation retainArguments]; 
[myInvocation invoke];
[myInvocation getReturnValue: &result];
NSLog(@"The result is: %@", result); [pool drain];
return0;
}
复制代码

http://www.j2megame.org/index.php/content/view/2635/165.html

NSMethodSignature和NSInvocation的使用

动态调用方法时会用到,例子

-(NSString *)myMethod:(NSString *)param1 withParam2:(NSNumber *)param2 

    NSString *result = @"objc"; 
    NSLog(@"par = %@",param1); 
    NSLog(@"par 2 = %@",param2); 
    return result; 
}

-(void)invokeMyMethodDynamically 

    SEL selector = @selector(myMethod:withParam2:); 
    NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:selector];//获得类和方法的签名 
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; 
    //从签名获得调用对象 
    [invocation setTarget:self]; 
    //设置target 
    [invocation setSelector:selector];//设置selector 
    NSString *returnValue = nil; 
    NSString *argument1 = @"fist"; 
    NSNumber *argument2 = [NSNumber numberWithInt:102]; 
    [invocation setArgument:&argument1 atIndex:2];//设置参数,第一个参数index为2 
    [invocation setArgument:&argument2 atIndex:3]; 
    [invocation retainArguments];//retain一遍参数 
    [invocation invoke];//调用 
    [invocation getReturnValue:&returnValue];//得到返回值,此时不会再调用,只是返回值 
    NSLog(@"return value = %@",returnValue); 
}

另外一个例子:

SEL selector = @selector(myMethod:setValue2:);

NSMethodSignature *signature = [MyObject instanceMethodSignatureF orSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSign ature:signature];
[invocation setSelector:selector];

NSString *str1 = @"someString";
NSString *str2 = @"someOtherString";

//The invocation object must retain its arguments
[str1 retain];
[str2 retain];

//Set the arguments
[invocation setTarget:targetInstance];
[invocation setArgument:&str1 atIndex:2];
[invocation setArgument:&str2 atIndex:3];

[NSTimer scheduledTimerWithTimeIn terval:0.1 invocation:invocation repeats:YES]

NSInvocation的使用(转)的更多相关文章

  1. Objective-C中NSInvocation的使用

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

  2. iOS开发——网络篇——UIWebview基本使用,NSInvocation(封装类),NSMethodSignature(签名),JavaScript,抛异常,消除警告

    一.UIWebView简介 1.UIWebView什么是UIWebViewUIWebView是iOS内置的浏览器控件系统自带的Safari浏览器就是通过UIWebView实现的 UIWebView不但 ...

  3. NSInvocation

    NSInvocation 基本简介 NSInvocation是一个静态描绘的OC消息,也就是说,它是一个动作,这个动作可以变成一个对象.NSInvocation对象在对象和对象之间和应用程序和应用程序 ...

  4. IOS NSInvocation用法简介

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

  5. NSInvocation Basics

    In this article I'm going to cover the basics and usages of NSInvocation. What is NSInvocation? Appl ...

  6. ios NSMethodSignature and NSInvocation 消息转发

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

  7. 利用NSInvocation对方法进行抽象,实现对方法的加锁

    我们在实际开发中须要对离散的方式加锁实现线程安全,当然我们有多种实现方式,这仅仅是当中一种,使用起来比較方便 + (id)performSelectorWithTarget:(id)target se ...

  8. iOS NSInvocation的学习

    用途: NSInvocation的作用和performSelector:withObject:的作用是一样的:用于iOS编程中调用某个对象的消息. performSelector:withObject ...

  9. 第16月第8天 NSInvocation存储 函数指针 va_arg lldb

    1.NSInvocation存储 -(void)setInvok:(id)target sel:(SEL)sel key:(id)key { if(!target) return; NSMethodS ...

随机推荐

  1. okhttputils开源库的混淆配置(Eclipse)

    #=====================okhttputils框架===================== #====okhttputils==== -libraryjars libs/okht ...

  2. sublime text修改TAB缩进为空格

    在sublime text中将TAB缩进直接转化为4个空格,可以按照如下方式操作: 菜单栏: Preferences -> Settings – More -> Syntax Specif ...

  3. MyBatis(3.2.3) - Configuring MyBatis using XML, typeHandlers

    As discussed in the previous chapter, MyBatis simplifies the persistent logic implementation by abst ...

  4. 【TOMCAT】Tomcat gzip压缩传输数据

    概述 由于我们项目的三维模型文件非常大,为了提高传输速度,在服务端对其做zip压缩处理非常有必要,能够极大的提高传输速度. 配置 首先需要修改web.xml中请求的数据文件的mime类型的mappin ...

  5. 教您如何使用SQL中的SELECT LIKE like语句

    LIKE语句在SQL有着不可替代的重要作用,下文就将为您介绍SQL语句中SELECT LIKE like的详细用法,希望对您能有所帮助. LIKE语句的语法格式是:select * from 表名 w ...

  6. wpf DataGrid 双击获取当前行的控件

    <DataGrid Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top& ...

  7. css 笔记——设置禁用中文输入法

    ime-mode ime-mode的语法解释如下: ime-mode : auto | active | inactive | disabled 取值: auto  : 默认值.不影响IME的状态.与 ...

  8. UVa11384

    题意:给定正整数n,求把1,2,--,n中所有书都变成0的最少操作次数,每次操作可从序列中选择一个或多个整数,同时减去一个相同的正整数. 分析:如1,2,3,4,5,6, 第一步将4,5,6同时减4, ...

  9. 分布式之高性能IO组件

    因为毕业设计(实时分析大型数据流),开始对分布式并行计算做研究,第一个问题就是通讯.高性能的通讯是整个系统性能的基本保障. 方案 就目前的经验来讲,最好的通信选择是:异步非阻塞IO + 资源池. 异步 ...

  10. linux 常用软件安装-目录

    nginx apache php mysql oracle tomcat memcached mongodb sqlserver