`

ios NSInvocation简单使用

 
阅读更多

在ios直接调用某个对象的消息是方法有两种:

一:performselector:withObject:

二:invocation

 

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

 

NSInvocation可以处理参数、返回值。会java的人都知道凡是操作,其实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];
}

 

 

调用步骤:

- (NSString *) myMethod:(NSString *)param1 withParam2:(NSNumber *)param2{
	
	NSString *result = @"Objective-C";
	NSLog(@"Param 1 = %@", param1);
	NSLog(@"Param 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];
	
	[invocation setSelector:selector];

	NSString *returnValue = nil;
	NSString *argument1 = @"First Parameter";
	NSNumber *argument2 = [NSNumber numberWithInt:102];
	
	[invocation setArgument:&argument1 atIndex:2];
	[invocation setArgument:&argument2 atIndex:3];
	[invocation retainArguments];
	[invocation invoke];
	[invocation getReturnValue:&returnValue];
	
	NSLog(@"Return Value = %@", returnValue);
}

 


 

 

To do this, you need to follow these steps:
1. Form a SEL value using the name of the method and its parameter names (as
explained in Recipe 1.7).
2. Form a method signature of type NSMethodSignature out of your SEL value.
3. Form an invocation of type NSInvocation out of your method signature.
4. Tell the invocation what object you are targeting.
5. Tell the invocation what selector in that object you want to invoke.
6. Assign any arguments, one by one, to the invocation.
7. Invoke the method using the invocation object and demand a return value (if any).

分享到:
评论
1 楼 ak478288 2012-02-29  
兄弟,你上半部分的文章为什么和我的原创文章一模一样呢?如果是引用,请加原文链接,谢谢

相关推荐

    iOS中NSInvocation的基本用法教程

    但是对于>2个的参数或者有返回值的处理,那performSelector:withObject就显得有点有心无力了,那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作 NSInvocation的基本使用 方法签名类 // 方法...

    OBJECTIVE-C编程之道 IOS设计模式解析电子书+源代码

    策略19.1 何为策略模式19.2 何时使用策略模式19.3 在UITextField中应用验证策略19.4 总结第20章 命令20.1 何为命令模式20.2 何时使用命令模式20.3 在Cocoa Touch框架中使用命令模式20.3.1 NSInvocation对象20.3.2 ...

    InvocationDemo

    NSInvocation的作用和performSelector:withObject:的作用是一样的:用于iOS编程中调用某个对象的消息。 performSelector:withObject:调用一些参数较少的消息是比较方便的,但是对于参数个数大于2的消息,使用...

    ISInvocationHookProxy:挂钩目标的每个 NSInvocation 的代理对象

    ISInvocationHookProxy 挂钩目标的每个 NSInvocation 的代理对象。用法 NSString *object = [[ NSString alloc ] init ];ISInvocationHookProxy *proxy = [[ISInvocationHookProxy alloc ] initWithTarget: object];...

    队列:iOS的持久后台作业队列

    尽管NSOperation和NSOperationQueue在某些重复性问题上很好地工作,而在其他问题上则可以使用NSInvocation ,但iOS并未真正包含一组用于轻松管理大量任意背景任务的工具。 EDQueue提供了一个高级接口,用于使用和...

    iOS中最全的各种定时器使用教程

    ,下面将给大家详细介绍关于iOS定时器使用的相关内容,话不多说了,来一起看看详细的介绍吧。 一. NSTimer NSTimer的初始化方法有以下几种: 会自动启动, 并加入 MainRunloop 的 NSDefaultRunLoopMode 中, 注意: ...

    DesignPatterns-iOS:使用适用于iOS环境的设计模式的应用示例

    DesignPatterns-iOS 使用设计模式的示例应用程序。 在此示例中,我使用了: MVC:模型视图控制器。 单例:在整个应用程序中仅创建一个实例。 外观:到复杂子系统的单一接口。 装饰器:在不修改对象代码的情况下...

    DynamicOC:深入理解iOS热修复原理

    深入理解iOS热修复原理背景顾名思义热bug就是使App有了线上bug的能力,但是遗憾的是苹果出于安全的考虑考虑了热修复。虽然App审核加快了,但是依然无法很好的控制线上bug的影响范围。 JSPatch存在审核风险,所以我们...

    iOS runtime forwardInvocation详解及整理

    iOS runtime forwardInvocation详解 代码: TestModel - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { if(aSelector == @selector(testMethod)) { return [NSMethodSignature ...

    YAAdapterTableViewWithResponderChain

    1.创建一个扩展UITableViewAdapter的适配器,覆盖将要使用的委托 2.然后设置UITableView [ _tableView setAdapter : [ self adapter ] ] 3.接下来覆盖tableView的超类中的func - ( void ) rountEvent : ( NSString...

    _objc_msgForward_demo

    _objc_msgForward_demo用来测试消息转发机制对象查找selector时,先查找cachelist,如果没有则查找methodlist,如果还没有就查找父类的methodlist都没有是... - (void)forwardInvocation:(NSInvocation *)anInvocati

    附加和实用程序使Core Data框架更易于并发。-Swift开发

    CWCoreData ===========...NSInvocation还具有其他功能,以支持在线程边界上通过NSManagedObject实例进行调用。 创建该项目的目的是用作其他Xcode项目的子项目。 另外,该项目可以用作git子模块。 这个项目有一个独立的

    OCMethodTrace:跟踪任何Objective-C方法调用

    OCMethodTrace:跟踪任何Objective-C方法调用

Global site tag (gtag.js) - Google Analytics