博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS中perform+@selector多参数传递
阅读量:5885 次
发布时间:2019-06-19

本文共 2695 字,大约阅读时间需要 8 分钟。

hot3.png

iOS中performSelector实现多参数传递

关于performSelector实现多个参数传递,其实有2种方案,第一种是使用 NSInvocation,第二种是封装参数。按照参数传递的原则,例如c++中的线程,我们只能传递一个参数,但我们可以将参数封装进结构体或者class也是一种优秀的方案。

两种方法的比较,第一种使用了Runtime反射机制,效率又说折扣,可读性也不好好,第二种方法,效率较高,可读性也比较好。所以对比而言,推荐第二种将参数封装进结构体或者对象,作为DTO的作用。

第一种方法NSInvocation
- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects{    // 方法签名(方法的描述)    NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];    if (signature == nil) {              //可以抛出异常也可以不操作。    }        // NSInvocation : 利用一个NSInvocation对象包装一次方法调用(方法调用者、方法名、方法参数、方法返回值)    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];    invocation.target = self;    invocation.selector = selector;        // 设置参数    NSInteger paramsCount = signature.numberOfArguments - 2; // 除self、_cmd以外的参数个数    paramsCount = min(paramsCount, objects.count);    for (NSInteger i = 0; i < paramsCount; i++) {        id object = objects[i];        if ([object isKindOfClass:[NSNull class]]) continue;        [invocation setArgument:&object atIndex:i + 2];    }        // 调用方法    [invocation invoke];        // 获取返回值    id returnValue = nil;    if (signature.methodReturnLength) { // 有返回值类型,才去获得返回值        [invocation getReturnValue:&returnValue];    }        return returnValue;}

当然,为了保证线程意义,我们可以如下

- (void) performSelectorOnMainThread:(SEL)selector withObject:(id)arg1 withObject:(id)arg2 waitUntilDone:(BOOL)wait{NSMethodSignature *sig = [self methodSignatureForSelector:selector];if (!sig) return;NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig];[invo setTarget:self];[invo setSelector:selector];[invo setArgument:&arg1 atIndex:2];[invo setArgument:&arg2 atIndex:3];[invo retainArguments];[invo performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:wait];}

第二种方法[参数封装](推荐)

我们还可以将参数进行封装成一个结构体,Class,或者是字典和其他集合,然后定义一个单参数的方法也是可取的,这里就不给出例子了

-(void)askWorker:(NSString *) name withID:(NSInteger) money AtDate:(NSDate *)date{      NSLog(@"%@---@ld---%@",name,(long)money,date);}-(void) askWorker:(NSObject *)args{        if([args isKindOfClass:[NSDictonary class]]    {       NSDictionary * dict = (NSDictionary *)args;      [self askWorker:dict[@"name"] withID:(NSInteger)dict[@"ID"] AtDate:dict[@"date"]];    }else if([args isKindOfClass:[UserProfile class]]){       UserProfile * profile = (UserProfile *)args;       [self askWorker:profile.name withID:profile.ID AtDate:profile.date];    }}

调用如下

   NSDictionary * dict = @{@"name":@"zhangsan",@"ID":@20102847,@"date":[NSDate dateWithTimeIntervalSince1970:0]};   [[TestDict share] performSelector:@selector(askWorker:) withObject:dict];

转载于:https://my.oschina.net/ososchina/blog/644117

你可能感兴趣的文章
TextKit简单示例
查看>>
网格最短路径算法(Dijkstra & Fast Marching)(转)
查看>>
软链接和硬链接详解
查看>>
Redis_master-slave模式
查看>>
彻底卸载删除微软Win10易升方法
查看>>
SWT/JFACE之环境配置(一)
查看>>
应用程序日志中总是说MS DTC无法正确处理DC 升级/降级事件,是什么意思
查看>>
mybatis数据处理的几种方式
查看>>
作业2
查看>>
远程主机探测技术FAQ集 - 扫描篇
查看>>
C++中调用python函数
查看>>
Nomad添加acl认证
查看>>
“TI门外汉”网路知识笔记一 OSI参考模型
查看>>
你不需要jQuery(五)
查看>>
DatanodeDescriptor说明
查看>>
ServlertContext
查看>>
Python WOL/WakeOnLan/网络唤醒数据包发送工具
查看>>
sizeof(long)
查看>>
pxe网络启动和GHOST网克
查看>>
2.5-saltstack配置apache
查看>>