请选择 进入手机版 | 继续访问电脑版

不一样的方式实现performSelector接收多个参数

发表于 2016-07-24 23:41 显示全部楼层 41 1526

本帖最后由 花菜ChrisCai 于 2016-7-25 00:16 编辑

开发中偶尔有需求使用performSelector实现多个参数,

常规的方式是自定义一个performSelector方法并接收一个数组作为参数

- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects;

在方法内部通过遍历数组,获取方法的参数,这确实是个好方法,

不过当我们需要给某个参数传递nil的时候,这个方法就不适用了,因为数组中不能存nil


下面尝试一种非常规的方法,请看~

/// 该方法接收一个方法的签名,和可变参数
- (id)performSelector:(SEL)aSelector withObjects:(id)object,...;

下面看看具体实现

- (id)performSelector:(SEL)aSelector withObjects:(id)object,... {
   
    // 获取方法签名(方法的描述)
    NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:aSelector];
    if (signature == nil) {
        NSAssert(false, @"牛逼的错误,找不到 %@ 方法",NSStringFromSelector(aSelector));
    }
    // 包装方法
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    // 设置方法调用者
    invocation.target = self;
    // 设置需要调用的方法
    invocation.selector = aSelector;
    // 获取除去self、_cmd以外的参数个数
    NSInteger paramsCount = signature.numberOfArguments - 2;
    // 设置参数
    va_list params;
    va_start(params, object);
    int i = 0;
    // [GKEndMark end] 是自定义的结束符号,仅此而已,从而使的该方法可以接收nil做为参数
    for (id tmpObject = object; (id)tmpObject != [GKEndMark end]; tmpObject = va_arg(params, id)) {
        // 防止越界
        if (i >= paramsCount) break;
        // 去掉self,_cmd所以从2开始
        [invocation setArgument:&tmpObject atIndex:i + 2];
        i++;
    }
    va_end(params);
    // 调用方法
    [invocation invoke];
    // 获取返回值
    id returnValue = nil;
    if (signature.methodReturnType) {
        [invocation getReturnValue:&returnValue];
    }

    return returnValue;
}
// 该类仅仅用于自定义的结束符号
#import "GKEndMark.h"

@implementation GKEndMark

+ (instancetype)end {
    static id instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self class] new];
    });
    
    return instance;
}

@end

具体使用请看下图

1.png

以上为方法的具体实现,已经做了详细的注释了,就不多做解释了,

不过该方法还有个局限性就是当调用的方法返回值不是对象类型时就会崩了(系统的这类似的方法也没有返回基本数据类型的,不知道是不是我想太多了,)

想了蛮久不知道该如何解决,如果你有好的解决方案,请联系我,谢谢~




评分

参与人数 2学币 +7 收起 理由
小兰老师 + 3 赞一个!
seemygo + 4 很给力!

查看全部评分

回复 使用道具
举报
ac2oye4j

发表于 11-21 16:16 显示全部楼层

HOHO~~~~~~ 淘宝客高佣采集店铺淘客鹊桥淘宝联盟分裂工具百宝箱,2017淘悠悠 店铺淘宝客采集软件 淘客上传助手 淘客大屏,适用于裂变 店铺淘宝客软件 批量采集高佣金代理贴牌代理 今年新版淘宝自然搜索引流技术--宝贝裂变引流,适用于淘宝任何行业卖家推广引流!欢迎加入淘客客高级QQ交流群:495864164 ;购买我们的引流工具,半小时学会作,售后有保障,提供技术支持!! 我们的淘宝客软件有以下,诚招代理: 2017年11月,最新版极速裂变软件,双模式,服务器稳定,淘宝引流利器,适用于任何淘宝店铺;诚招代理;VIP帐号优惠出售,包教包会,免费试用! 欢迎加入信阳天银网络公司高级QQ交流群:495864164 ; 最新淘宝运营方法,一个淘宝店,一天成交50单以上的技术,培训新学员!
回复 支持 反对 使用道具
举报
cocoabird

发表于 02-09 02:46 显示全部楼层

必须给个赞!

回复 支持 反对 使用道具
举报
p出我世界

发表于 02-08 19:11 显示全部楼层

无需回复的,我们保持沉默,如需回复的,就回21个字!

回复 支持 反对 使用道具
举报
loverol

发表于 02-08 18:52 显示全部楼层

回复 支持 反对 使用道具
举报
p出我世界

发表于 02-08 12:12 显示全部楼层

必须给个赞!

回复 支持 反对 使用道具
举报
p出我世界

发表于 02-08 06:52 显示全部楼层

围观楼主

回复 支持 反对 使用道具
举报
甜甜车

发表于 02-08 06:50 显示全部楼层

祝愿小码哥越来越红火!!红红火火恍恍惚惚!

回复 支持 反对 使用道具
举报
南瑟1

发表于 02-08 06:49 显示全部楼层

  ╭══╮ ┌══════┐

  ╭╯让路║═‖ 酱油专用车 ‖

  ╰⊙═⊙╯ └══⊙═⊙═~. 作为一个资深的酱油党,我们需要做的不仅仅是路过,在路过的同时 还要关心楼主,鼓励楼主,在这个冷漠的时代,给予楼主温暖。酱油党莅临的地方,不仅仅是挽尊,不仅仅是消灭零回复,酱油

回复 支持 反对 使用道具
举报
旧霾街

发表于 02-08 05:11 显示全部楼层

1 先请大家注意我的头像。看到什么诡异的吗。 2 然后请大家仔细看我的ID,有什么内涵? 3 没看出来就默念我的ID 十遍,然后结合我的头像一起看!! 4 好了,你继续往楼下看吧,我就是来混脸熟的。

回复 支持 反对 使用道具
举报
1234下一页

发表新文章
花菜ChrisCai

小码哥会员

1

学分

207

学币

288

积分

小码哥会员

Rank: 3Rank: 3

积分
288

小码哥iOS学员勋章活动达人勋章真土豪勋章勋章意见领袖勋章关注小码哥教育公众号关注新浪微博小码哥周年庆杯子小码哥周年庆鼠标垫小码哥周年庆T恤

Ta的主页 发消息
精华帖排行榜

精彩推荐

  • 关注小码哥教育