NSInvocation的使用(转)
转载自: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 -(void)invokeMyMethodDynamically 另外一个例子: SEL selector = @selector(myMethod:setValue2:);
NSMethodSignature *signature = [MyObject instanceMethodSignatureF orSelector:selector]; NSString *str1 = @"someString"; //The invocation object must retain its arguments //Set the arguments [NSTimer scheduledTimerWithTimeIn terval:0.1 invocation:invocation repeats:YES] |
NSInvocation的使用(转)的更多相关文章
- Objective-C中NSInvocation的使用
OC中调用方法某个对象的消息呦两种方式: #1. performanceSelector: withObject: #2. NSInvocation. 第一个PerformaceSelector比较常 ...
- iOS开发——网络篇——UIWebview基本使用,NSInvocation(封装类),NSMethodSignature(签名),JavaScript,抛异常,消除警告
一.UIWebView简介 1.UIWebView什么是UIWebViewUIWebView是iOS内置的浏览器控件系统自带的Safari浏览器就是通过UIWebView实现的 UIWebView不但 ...
- NSInvocation
NSInvocation 基本简介 NSInvocation是一个静态描绘的OC消息,也就是说,它是一个动作,这个动作可以变成一个对象.NSInvocation对象在对象和对象之间和应用程序和应用程序 ...
- IOS NSInvocation用法简介
IOS NSInvocation用法简介 2012-10-25 19:59 来源:博客园 作者:csj007523 字号:T|T [摘要]在 iOS中可以直接调用某个对象的消息方式有两种,其中一种就是 ...
- NSInvocation Basics
In this article I'm going to cover the basics and usages of NSInvocation. What is NSInvocation? Appl ...
- ios NSMethodSignature and NSInvocation 消息转发
1.首先获取消息转发时连个函数内部具体内容 MARK:这里是拿[@"xxxxx" length]调用拿来举例说明 (lldb) po signature <NSMethodS ...
- 利用NSInvocation对方法进行抽象,实现对方法的加锁
我们在实际开发中须要对离散的方式加锁实现线程安全,当然我们有多种实现方式,这仅仅是当中一种,使用起来比較方便 + (id)performSelectorWithTarget:(id)target se ...
- iOS NSInvocation的学习
用途: NSInvocation的作用和performSelector:withObject:的作用是一样的:用于iOS编程中调用某个对象的消息. performSelector:withObject ...
- 第16月第8天 NSInvocation存储 函数指针 va_arg lldb
1.NSInvocation存储 -(void)setInvok:(id)target sel:(SEL)sel key:(id)key { if(!target) return; NSMethodS ...
随机推荐
- Hibernate的回调与拦截
在Hibernate中,有两种方式可以捕获实体对象的GRUD操作并执行相应的处理 Hibernate回调(org.hibernate.classic.Lifecycle接口): //Provides ...
- 关于Talend的Patch分支对应Eclipse开发环境的配置总结.
给产品打patch有时候会遇到很多问题,给产品打patch而且大多数是给很多老版本的Studio打,而且要有对应的patch的开发环境. 但是不巧有些patch对应的git仓库目录结构和一些其他版本的 ...
- Dubbo服务调用的动态代理和负载均衡
Dubbo服务调用的动态代理及负载均衡源码解析请参见:http://manzhizhen.iteye.com/blog/2314514
- pc端有弹出层 并有滚动的时候遇到的问题以及解决
有时候页面会遇到这样一个问题,页面有个弹出层 ,弹出层是有动条的,当弹出层滚完的时候,后面的页面也会滚动,但是我们希望是后面的页面不滚动;代码如下 1:弹出层出现的时候设置 $('body').css ...
- 7月15日学习之BOM
setTimeout() //延时器,只执行一次代码 clearTimeout() //清除演示器 setIntervla() //定时器,根据指定时间间隔执行一次代码 clearInterval() ...
- Java Concurrency - Phaser, Controlling phase change in concurrent phased tasks
The Phaser class provides a method that is executed each time the phaser changes the phase. It's the ...
- Linux 命令 - ps: 显示当前进程的快照
命令格式 ps [options] 实例 a) 查看所有的进程. huey@huey-K42JE:~$ ps aux | head USER PID %CPU %MEM VSZ RSS TTY STA ...
- 【AngularJs】---表单验证
1. 必填项 验证某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可: <input type="text" required /> 2 ...
- PetShop
Microsoft .NET Pet Shop 4:将 ASP.NET 1.1 应用程序迁移到 2.0 发布日期: 2006-5-9 | 更新日期: 2006-5-9 适用于:Microsoft .N ...
- JAVA之数据溢出
Integer在java中属于包装类,既能用于字符串与整型的转换,也能用于拆箱与装箱 package ABC; public class A{ public static void main(Stri ...