`

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的基本使用 方法签名类 // 方法...

    ios-简单选择器.zip

    这个“ios-简单选择器.zip”文件很可能包含了一个示例项目,演示了如何在iOS应用中自定义选择器的使用。下面将详细介绍选择器的概念、工作原理以及如何自定义。 选择器在Objective-C中是SEL类型的,它是一个指向...

    2018秋招iOS面试总结

    - SQLite:基本SQL操作,结合FMDB库在iOS中的使用。 - UserDefaults:简单数据的存储和读取。 7. **Apple框架和API**: - Core Location:获取和处理用户位置信息。 - Core Data:用于应用程序的数据模型层。 ...

    ios-JS_OC反射交互.zip

    我们可以使用`NSInvocation`、`NSMethodSignature`等类来实现。例如,我们可以根据解析出的函数名和参数类型,创建`NSInvocation`实例,并调用`invokeWithTarget:`来执行对应的函数。 以下是一个简单的示例流程: ...

    iOS消息转发机制在项目中的应用

    3. **错误处理**:通过捕获未定义的方法,可以优雅地处理因误操作或API变更导致的错误,而不是简单地崩溃。 4. **动态插件化**:在动态加载插件或扩展功能的场景下,消息转发能帮助对象找到正确的方法实现,即使...

    ios-对象的消息转发机制.zip

    - **错误处理**:当对象接收到不期望的消息时,可以通过消息转发机制优雅地处理错误,而不是简单的崩溃。 - **调试和监控**:在开发过程中,可以利用消息转发来记录未处理的消息,帮助定位潜在的问题。 - **KVO...

    iOS-多线程之NSOperation - iOS知识库1

    总之,NSOperation和NSOperationQueue为iOS开发者提供了一种高效、易用的方式来实现多线程编程,它们提供了取消、依赖关系、自定义行为等功能,使得处理复杂任务变得更加简单。在实际开发中,可以根据需求选择合适的...

    iOS 4 Programming Cookbook

    - **NSMethodSignature与NSInvocation**:掌握如何使用`NSMethodSignature`和`NSInvocation`来动态调用对象的方法。 - **性能考虑**:探讨动态调用与静态调用之间的性能差异。 - **案例分析**:通过具体的代码...

    iOS seletor传参

    以下是一个简单的示例,展示了如何使用`NSInvocation`传递参数: ```objc SEL selector = @selector(myMethod:withValue:); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self ...

    iOS消息转发机制及避免崩溃的解决方案.pdf

    例如,我们可以在`- (void)forwardInvocation:(NSInvocation *)anInvocation`中实现通用的错误处理逻辑,当遇到未知方法时,不再简单地崩溃,而是记录日志并给出提示,提高应用的健壮性。 在实际开发中,避免程序...

    iOS并发编程指南

    在iOS开发中,掌握并发编程是提升应用性能和用户体验的关键。并发编程允许应用程序同时执行多个任务,从而充分...在实际开发中,结合使用GCD和Operation Queues可以更好地管理和优化并发任务,实现高性能的iOS应用。

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

    本文将深入探讨三种常见的iOS定时器:NSTimer、GCD定时器以及CADisplayLink,并详细讲解它们的使用方法。 一、NSTimer NSTimer是Foundation框架中的一员,它基于RunLoop工作,能够按照设定的时间间隔执行指定的...

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

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

    ios并发编程指南(中文版)

    ### iOS并发编程指南(中文版) #### 一、概述 《iOS并发编程指南》是一部详细介绍如何在iOS应用程序中实现高效并发编程的技术文档。该指南由苹果公司原作,经过Kevin的精心翻译,使得中文读者能够更好地理解并发...

    iOS如何实现强制转屏、强制横屏和强制竖屏的实例代码

    然而,上述方法并不总是奏效,因为从iOS 6开始,Apple推荐使用`UIViewController`的`supportedInterfaceOrientations`和`shouldAutorotate`方法来控制屏幕旋转。你应该在你的视图控制器中重写这两个方法,以允许或...

    ios试题总结

    下面是一个使用委托模式的简单示例: ```objective-c @protocol CarDelegate - (void)carDidStartMoving; @end @interface Car : NSObject @property (nonatomic, weak) id<CarDelegate> delegate; @end @...

    OC-performSelector

    你可以通过`+[NSInvocation invocationWithMethodSignature:]`创建一个`NSInvocation`对象,并使用`setSelector:`设置选择器,`setTarget:`设置目标对象,`setArgument:atIndex:`设置参数。 3. **performSelector的...

    C++ oc 互相调用

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]]; [invocation setTarget:self]; [invocation invoke]; } @end ``` 注意,OC调用C++时,...

    多线程编程指南

    `NSInvocationOperation`是`Operation`的一个子类,它可以将一个`NSInvocation`实例包装成一个异步任务,从而使得任何遵循`NSInvocable`协议的方法都可以异步执行。 **2.4 NSBlockOperation** `NSBlockOperation`...

Global site tag (gtag.js) - Google Analytics