@在 iOS中可以直接调用某个对象的消息方式有2种:
1.performSelector:withObject: 2.NSInvocation
第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那就需要做些额外工作才能搞定。那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作.
@其实也是工作所使,原先只是知道,但没实际的用过,果然工作的时候才会实际的区去运用各个知识点.
// // HMTTest1.h // Created by HMT on 14-8-3. // #import <Foundation/Foundation.h> @interface HMTTest1 : NSObject - (NSString *)addTestString:(NSString *)testString; @end // // HMTTest1.m // Created by HMT on 14-8-3. // #import "HMTTest1.h" @implementation HMTTest1 - (NSString *)addTestString:(NSString *)testString{ NSString *string = [NSString stringWithFormat:@"这是一个关于%@的测试Demo", testString]; return string; } @end - (void)testOfNSInvocation{ /*******************************normal方式*******************************/ HMTTest1 *test1 = [[HMTTest1 alloc] init]; NSString *normalString = [test1 addTestString:@"直接调用方法"]; NSLog(@"normal = %@",normalString); NSLog(@"normal = %@",[test1 performSelector:@selector(addTestString:) withObject:@"performSelector:withObject"]); /*******************************NSInvocation方式*******************************/ NSString *testString = @"haha"; // 方法签名类,需要被调用消息所属的类HMTTest1 ,被调用的消息addTestString: NSMethodSignature *signature = [[HMTTest1 class] instanceMethodSignatureForSelector:@selector(addTestString:)]; // 根据方法签名创建一个NSInvocation NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:signature]; // 设置调用者也就是HMTTest1的实例对象,也就是test1 [myInvocation setTarget:test1]; // 设置被调用的消息 [myInvocation setSelector:@selector(addTestString:)]; // 如果此消息有参数需要传入,参数是void*类型,需要注意的是atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target 和selector占用 //id(泛型对象)和void*(泛型指针)并非完全一样 [myInvocation setArgument:&testString atIndex:2]; // 定义接收结果的变量 NSString *result = nil; // retain所有参数,防止参数被释放dealloc [myInvocation retainArguments]; // 消息调用 [myInvocation invoke]; // 将得到的结果赋值给定义的变量 [myInvocation getReturnValue: &result]; NSLog(@"The NSInvocation invoke string is: %@", result); // //获得返回值类型 // const char *returnType = signature.methodReturnType; // // 声明返回值变量 // id returnValue; // // 如果没有返回值,也就是消息声明为void,那么returnValue=nil // if( !strcmp(returnType, @encode(void)) ){ // // returnValue = nil; // // } // // 如果返回值为对象,那么为变量赋值 // else if( !strcmp(returnType, @encode(id)) ){ // // [myInvocation getReturnValue:&returnValue]; // // } // else{ // // } /*******************************@encode(aType) 可以返回该类型的 C 字符串(char *)的表示*******************************/ NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],@"key1",[NSNumber numberWithDouble:100.00f],@"key2",[NSNumber numberWithInt:200],@"key3",[NSNumber numberWithFloat:300.0f], @"key4", nil]; for(NSString *key in dic){ id value = [dic valueForKey:key]; if([value isKindOfClass:[NSNumber class]]){ const char * pObjCType = [((NSNumber*)value) objCType]; if (strcmp(pObjCType, @encode(int)) == 0) { NSLog(@"字典中key=%@的值是int类型,值为%d",key,[value intValue]); } if (strcmp(pObjCType, @encode(float)) == 0) { NSLog(@"字典中key=%@的值是float类型,值为%f",key,[value floatValue]); } if (strcmp(pObjCType, @encode(double)) == 0) { NSLog(@"字典中key=%@的值是double类型,值为%f",key,[value doubleValue]); } if (strcmp(pObjCType, @encode(BOOL)) == 0) { NSLog(@"字典中key=%@的值是bool类型,值为%i",key,[value boolValue]); } } } }
NSInvocation的基本用法,布布扣,bubuko.com
原文地址:http://blog.csdn.net/hmt20130412/article/details/38360705