码迷,mamicode.com
首页 > 移动开发 > 详细

iOS开发——实用技术OC篇&?Invocation简单介绍

时间:2015-08-25 21:18:03      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:

Invocation简单介绍


方法一:运行时方法:(这里在之前的文章定时器的几种方法中说过:www.cnblogs.com/iCocos/p/4694581.html

 

1:创建一个签名:

NSMethodSignature *singature = [NSMethodSignature signatureWithObjCTypes:"v@:"]; 

这里我想如果你仔细的话肯定注意到了:后面的“v@:”,这里是运行时的语法
在这里是指一个方法
    •    v放回viod类型
    •    @一个id类型的对象
    •    :对应SEL
关于运行时这里不多介绍请查看笔者之前的文章,或者查看官方文档,这是一个iOS开发者必须会的知识点
2:通过前面创建一个请求,并且设置对应的target和SEL

  NSInvocation *vocation = [NSInvocation invocationWithMethodSignature:singature];
  vocation.target = self;
  vocation.selector = @selector(timeChange);


 3:在讲请求传到NSTimer中去实现定时

[NSTimer scheduledTimerWithTimeInterval:1 invocation:vocation repeats:YES]; 


方法二:对应类直接创建

   Signature签名: 在创建NSInvocation的时候, 必须传递一个签名对象
   签名对象的作用 : 用于获取参数的个数和方法的返回值
  注意点: 创建签名对象的时候不是使用NSMethodSignature类创建 \


    一:而是方法属于谁就用谁来创建

    NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(sendMessageWithNumber:andContent:status:)];

//    NSInvocation; 用来包装方法和对应的对象, 它可以存储方法的名称,对应的对象 ,对应的参数
    二: .创建一个NSInvocation对象

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];


  三:设置对应的属性

    invocation.target = self; // 保存方法所属的对象   
 // 给invocation设置的方法, 必须和签名中的方法一致   
 invocation.selector = @selector(sendMessageWithNumber:andContent:status:); // 保存方法名称

    // 第一个参数: 需要给指定方法传递的值
    //           + 第一个参数需要接收一个指针, 也就是传递值的时候需要传递地址
    // 第二个参数: 需要给指定方法的第几个参数传值
    四:实现参数的设置    

NSString *number = @"iCocos";


    // 注意: 设置参数的索引时不能从0开始, 因为0已经被self占用, 1已经被_cmd占用

    [invocation setArgument:&number atIndex:2];

    // 2.调用NSInvocation对象的invoke方法
    // 只要调用invocation的invoke方法, 就代表需要执行 \
    五:NSInvocation对象中指定对象的指定方法, 并且传递指定的参数

    [invocation invoke];


NSInvocation经典案例:多参数方法的封装:

 1 - (id)performSelector:(SEL)aSelector withObjects:(NSArray *)objects
 2 {
 3     //  1.创建签名对象
 4     NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:aSelector];
 5     
 6     // 判断传入的方法是否存储, 如果方法不存在签名对象为nil
 7     if (signature == nil) {
 8         // 传入的方法不存在
 9         NSString *info = [NSString stringWithFormat:@" -[%@ %@]:  unrecognized selector sent to instance", [self class], NSStringFromSelector(aSelector)];
10         
11         @throw [[NSException alloc] initWithName:@"一个牛B的错误" reason:info userInfo:nil];
12     }
13     
14     // 2.创建一个NSInvocation对象
15     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
16     
17      // 3.保存方法所属的对象
18     invocation.target = self;
19     
20     // 给invocation设置的方法, 必须和签名中的方法一致
21     //  4.保存方法名称
22     invocation.selector = aSelector;
23     
24     // 5.设置参数
25     /*
26      当前如果直接遍历参数数组来设置参数, 会存在问题
27      如果参数数组元素多余参数个数, 那么就会报错
28      */
29     NSUInteger arguments =  signature.numberOfArguments - 2;
30     /*
31      如果直接遍历参数值的个数, 会存在问题
32      如果参数的个数大于了参数值的个数, 那么数组会越界
33      */
34     NSUInteger objectsCount = objects.count;
35     /*
36      参数和参数值, 谁少就遍历谁
37      */
38     NSUInteger count = MIN(arguments, objectsCount);
39     
40     for (int i = 0; i < count; i++) {
41         NSObject *obj = objects[i];
42         // 处理数组参数中NSNull问题
43         if ([obj isKindOfClass:[NSNull class]]) {
44             obj = nil;
45         }
46         [invocation setArgument:&obj atIndex:i + 2];
47     }
48     
49     // 6.调用NSInvocation对象的invoke方法
50     [invocation invoke];
51     
52     id res = nil;
53     // 判断当前方法是否有返回值
54 //    NSLog(@"ReturnType = %zd", signature.methodReturnLength);
55     if ( signature.methodReturnLength != 0) {
56         // 7.获取返回值
57         // getReturnValue方法会将会去到的方法返回值赋值给传入的对象
58         [invocation getReturnValue:&res];
59     }
60     
61     return res;
62 }

 



以后我们有再多的参数都不用担心了,而且实现了各种优化,在上一篇我们使用JS调用OC的时候就没有这么麻烦了,直接传递一个参数(数组)进来就可以根据参数和对应的方法去实现相应的功

 

iOS开发——实用技术OC篇&?Invocation简单介绍

标签:

原文地址:http://www.cnblogs.com/iCocos/p/4758410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!