iOS -使用performSelector方法调用多个参数

系统的performSelector方法##

在<NSObject> 的协议中为我们调用SEL方法提供了几个协议方法

- (id)performSelector:(SEL)aSelector;  //直接调用方法
- (id)performSelector:(SEL)aSelector withObject:(id)object;//可以传入一个参数
 - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; //可以传入两个参数

so,问题来了,要是我们需要传入得参数大于两个怎么办?所以我就试试模拟系统调用方法的过程来实现调用方法可以传入多个参数的demo

系统的performSelector怎么调用的呢?##

第一步:根据SEL去实例化方法签名NSMethodSignature(方法签名中有方法的名称,参数和返回值)

NSMethodSignature *signature =[[self class] instanceMethodSignatureForSelector:aSelector];

第二步:判断方法签名是否存在,如果不存在,就不存在这个方法,如果存在,就通过签名拿到NSInvocation对象(NSInvocation中保存了方法所属于的对象|方法名称|参数|返回值等)

 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

第三步:判断参数个数,设置NSInvocation的对象设置参数,调用方法
这里注意哦
!!!!!签名中方法参数的个数:签名内部包含了self和_cmd,所以参数从第3个开始

[invocation setTarget:self];
[invocation setSelector:aSelector];
//签名中方法参数的个数,内部包含了self和_cmd,所以参数从第3个开始
NSInteger  signatureParamCount = methodSignature.numberOfArguments - 2;
NSInteger requireParamCount = objects.count;
NSInteger resultParamCount = MIN(signatureParamCount, requireParamCount);
for (NSInteger i = 0; i < resultParamCount; i++) 
{
   id  obj = objects[i];
   [invocation setArgument:&obj atIndex:i+2];
}
[invocation invoke];

第四步:返回值的处理

    id callBackObject = nil;
    if(methodSignature.methodReturnLength)
    {
        [invocation getReturnValue:&callBackObject];
    }
    return callBackObject;

步骤原理说完了,直接代码,代码亲切##

个人建议把这个方法增加到NSObject的分类中,以后方便调用
温馨提示:代码复制可用,要是喜欢就点个赞。

- (id)performSelector:(SEL)aSelector withObjects:(NSArray *)objects
  {
    NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:aSelector];
   if(methodSignature == nil)
     {
       @throw [NSException exceptionWithName:@"抛异常错误" reason:@"没有这个方法,或者方法名字错误" userInfo:nil];
       return nil;
     }
     else
     {
       NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
       [invocation setTarget:self];
       [invocation setSelector:aSelector];
       //签名中方法参数的个数,内部包含了self和_cmd,所以参数从第3个开始
       NSInteger  signatureParamCount = methodSignature.numberOfArguments - 2;
       NSInteger requireParamCount = objects.count;
       NSInteger resultParamCount = MIN(signatureParamCount, requireParamCount);
      for (NSInteger i = 0; i < resultParamCount; i++) {
        id  obj = objects[i];
        [invocation setArgument:&obj atIndex:i+2];
      }
     [invocation invoke];
    //返回值处理
    id callBackObject = nil;
    if(methodSignature.methodReturnLength)
    {
        [invocation getReturnValue:&callBackObject];
    }
    return callBackObject;
   }
 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,840评论 0 9
  • OC调用JS 首先我们创建一个WebView,加载一个本地的HTML文件 在webview加载完成时-(void)...
    45b645c5912e阅读 1,162评论 2 5
  • Objective-C中有两个NSObject,一个是NSObject类,另一个是NSObject协议。而其中NS...
    ScaryMonsterLyn阅读 775评论 0 2
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,237评论 0 7
  • 春花秋月,我一直想为你写一首歌。 遥记儿时的小巷, 雨水滴答滴答落在青石板的小路, 不停溅起水花一朵朵, 那一刻你...
    km少年阅读 190评论 0 0