<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont

简介: 每日更新关注:http://weibo.com/hanjunqiang  新浪微博1.SEL触发SEL就是selector的缩写,它表示Cocoa中的方法选择器,不明白?那请仔细了解Objective_C的运行时机制与Cocoa底层思想。

每日更新关注:http://weibo.com/hanjunqiang  新浪微博

1.SEL触发

SEL就是selector的缩写,它表示Cocoa中的方法选择器,不明白?那请仔细了解Objective_C的运行时机制与Cocoa底层思想。

SEL theSelector = @selector(methodWithInt:andInt:);


看了上面代码这下你明白了什么是SEL了吧,平时我们开发当中经常用到的。
有了SEL这样就可以触发方法调用了,

[self performSelector:theSelector]
[self performSelector:@selector(methodWithInt:andInt:)];

上面两句代码是同一个道理。

2. IMP触发

IMP其实就是一个函数指针的概念,就可以这么简单理解。

IMP theImplementation = [self methodForSelector:theSelector];

上面这句代码就是获取methodWithInt:andInt:这个方法的地址。

有了这个函数指针后,我们就可以触发方法:

theImplementation(self, theSelector, 30, 5);

第一个是对象,第二个SEL, 后面的传入的参数。

每日更新关注:http://weibo.com/hanjunqiang  新浪微博

3. objc_msgSend方法

这是Objc运行时的一个C方法,我们先看一个示列:

objc_msgSend(self, @selector(fly));

[self fly];

4. NSInvocation

NSInvocation相比上面几种方法,可以动态决定传入的参数个数。有了它,我们就可以实现…这样的变参API封装。
说得有点抽像,看代码更清楚:

假如我们实现了一个两个数相加的方法,

-(void)addNSNumber:(NSNumber *)first withNumber:(NSNumber *)second

我们可以用下面的方法来触发这个方法,并获取返回值。


NSNumber *arg1 = [NSNumber numberWithDouble:15.0]; 
NSNumber *arg2 = [NSNumber numberWithDouble:13.0];
 SEL selector = @selector(addNSNumber:withNumber:); 
NSMethodSignature *sig = [self methodSignatureForSelector:selector]; 
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; 
[invocation setTarget:self]; [invocation setSelector:selector]; 
[invocation setArgument:(void *)&arg1 atIndex:2];
 [invocation setArgument:(void *)&arg2 atIndex:3];
 [invocation invoke]; if ([sig methodReturnLength])
 { [invocation getReturnValue:&retval]; return retval; } return nil; }



代码很容易理解,我也不多做解释,有不明白的请留言。

每日更新关注:http://weibo.com/hanjunqiang  新浪微博

下面是变参封装, 写了两个NSObject的Extension(Category):

 
+ (NSInvocation *)createInvocationOnTarget:(id)target selector:(SEL)selector {
  return [NSObject createInvocationOnTarget:target selector:selector withArguments:nil];
}
 
+ (NSInvocation *)createInvocationOnTarget:(id)target selector:(SEL)selector withArguments:(id)arg1, ... {
  NSMethodSignature *sig = [target methodSignatureForSelector:selector];
  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
 
  [invocation setTarget:target];
  [invocation setSelector:selector];
 
 
 
  if(arg1) {
      va_list args;
      va_start(args, arg1);
 
      [invocation setArgument:(void *)&arg1 atIndex:2];
 
      id obj;
      int ct = 3;
 
      while( obj = va_arg(args, id) ) {
          NSLog(@"%@", obj);
          [invocation setArgument:(void *)&obj atIndex:ct];
 
          ct++;
      }
 
      va_end(args);
  }
 
 
  return invocation;
}

调用方法:

 
NSInvocation *invocation = [NSObject createInvocationOnTarget:mathInstance selector:selector withArguments: arg1, arg2, nil]; 
 
[invocation invoke];
[invocation getReturnValue:&retval];
 
return retval;



每日更新关注:http://weibo.com/hanjunqiang  新浪微博

目录
相关文章
|
7天前
|
NoSQL Cloud Native Redis
Redis核心开发者的新征程:阿里云与Valkey社区的技术融合与创新
阿里云瑶池数据库团队后续将持续参与Valkey社区,如过往在Redis社区一样耕耘,为开源社区作出持续贡献。
Redis核心开发者的新征程:阿里云与Valkey社区的技术融合与创新
|
6天前
|
关系型数据库 分布式数据库 数据库
PolarDB闪电助攻,《香肠派对》百亿好友关系实现毫秒级查询
PolarDB分布式版助力《香肠派对》实现百亿好友关系20万QPS的毫秒级查询。
PolarDB闪电助攻,《香肠派对》百亿好友关系实现毫秒级查询
|
7天前
|
消息中间件 Cloud Native Serverless
RocketMQ 事件驱动:云时代的事件驱动有啥不同?
本文深入探讨了云时代 EDA 的新内涵及它在云时代再次流行的主要驱动力,包括技术驱动力和商业驱动力,随后重点介绍了 RocketMQ 5.0 推出的子产品 EventBridge,并通过几个云时代事件驱动的典型案例,进一步叙述了云时代事件驱动的常见场景和最佳实践。
115053 1
|
8天前
|
弹性计算 安全 API
访问控制(RAM)|云上安全使用AccessKey的最佳实践
集中管控AK/SK的生命周期,可以极大降低AK/SK管理和使用成本,同时通过加密和轮转的方式,保证AK/SK的安全使用,本次分享为您介绍产品原理,以及具体的使用步骤。
101817 2
|
7天前
|
自然语言处理 Cloud Native Serverless
通义灵码牵手阿里云函数计算 FC ,打造智能编码新体验
近日,通义灵码正式进驻函数计算 FC WebIDE,让使用函数计算产品的开发者在其熟悉的云端集成开发环境中,无需再次登录即可使用通义灵码的智能编程能力,实现开发效率与代码质量的双重提升。
95393 2
|
5天前
|
物联网 PyTorch 测试技术
手把手教你捏一个自己的Agent
Modelscope AgentFabric是一个基于ModelScope-Agent的交互式智能体应用,用于方便地创建针对各种现实应用量身定制智能体,目前已经在生产级别落地。
|
21小时前
|
NoSQL Java Redis
使用Redis实例搭建网上商城的商品相关性分析程序
本教程将指导您如何快速创建实例并搭建网上商城的商品相关性分析程序。(ApsaraDB for Redis)是兼容开源Redis协议标准的数据库服务,基于双机热备架构及集群架构,可满足高吞吐、低延迟及弹性变配等业务需求。
17067 0
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
112734 12
|
12天前
|
SQL 存储 JSON
Flink+Paimon+Hologres 构建实时湖仓数据分析
本文整理自阿里云高级专家喻良,在 Flink Forward Asia 2023 主会场的分享。
71342 1
Flink+Paimon+Hologres 构建实时湖仓数据分析

热门文章

最新文章