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 ...
随机推荐
- js实现堆排序
<script type="text/javascript"> var arr = [22, 31, 1, 9, 99, 68, 55, 30]; function h ...
- 关于修改Eclipse工作空间对应的文件夹名称之后的处理.
把文件夹名字从"xhkong"变成"xhkong(maintenance5.6)"之后打开这个工作空间. 导入git仓库我发现了一个之前没有发现的小技巧. 导入 ...
- vsftp实现ftps加密传输数据
FTP明文传输数据,不太安全,ftp+ssl可以实现传输加密=ftps 01.创建FTP用户 user -d /ftp_www -s /sbin/nologin mvpbang echo " ...
- Java Concurrency - wait & notify, 等待通知机制
生产者消费者问题是一个常见的多线程同步案例:一组生产者线程和一组消费者线程共享一个初始状态为空.大小为 N 的缓冲区.只有当缓冲区没满的时候,生产者才能把消息放入缓冲区,否则必须等待:只有缓冲区不空的 ...
- Lombok(1.14.8) - @SneakyThrows
@SneakyThrows @SneakyThrows,声明异常. package com.huey.lombok; import java.io.UnsupportedEncodingExcepti ...
- 【转】Github入门教程
原文 http://www.eoeandroid.com/thread-274556-1-1.html [初识Github] 首先让我们大家一起喊一句“Hello Github”.YEAH!就是这样. ...
- Android之简单页面跳转
Uri.parse方法返回的是一个URL类型,通过URL可以访问一个网络上的或者本地资源,Intent()方法是调用哪个组件来打开这个URL. package com.example.web; imp ...
- MyBatis参数传入集合之foreach动态sql
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合.foreach元素的属性主要有item,index,collection,open,separator,close.ite ...
- maven入门程序(3)
欢迎转载交流:http://www.cnblogs.com/shizhongtao/p/3472864.html 这里我将展示如何用maven快速创建一个基于spring的web框架.创建步骤和上一篇 ...
- bzoj 1040 骑士
这题真不爽,各种WA,写个题解浏览器还挂了,真不爽. 所以不多说了,就说关于判断是否是父节点的问题,不能直接判,会有重边,这种情况只能用编号判,传进去入边的编号,(k^1) != fa,这样就可以了. ...