NT_iOS笔记—Runtime

1.背景、定义

1.1 Apple开源的Runtime代码

1.2 Objective-C会尽可能的将编译要做的事情推迟到运行时。 Objective-C 语言不仅需要一个编译环境,同时也需要一个运行时系统(runtime)来执行编译好的代码。

1.3 对于下面的简单方法:

[receiver message];
编译器将会转化为:

objc_msgSend(receiver, selector)//无参数
objc_msgSend(receiver, selector, arg1, arg2, ...)//有参数

2.消息传递流程

① 检查receiver是否为nil,如果receiver为空,则会将 selector也设置为空,直接返回到消息调用的地方,否则下一步

② 根据SEL到当前类中查找对应的IMP,先会在cache中检索它,如果找到了就根据函数指针跳转到这个函数执行,否则下一步

③ 检索当前类对象中的方法表(method list),如找到了,加入cache中,并且就跳转到这个函数之行,否则下一步

④ 从父类中寻找,直到根类:NSObject类。找到了就将方法加入对应类的cache表中,如果找不到则进行动态方法决议(3),仍解决不了则下一步

⑤ 进入消息转发(4),仍解决不了则下一步

⑥ 程序崩溃

3.动态方法

+ (BOOL)resolveClassMethod:(SEL)sel __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
+ (BOOL)resolveInstanceMethod:(SEL)sel __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

这个函数分别添加实例方法实现和类方法实现
在运行时
(runtime),没有找到SELIML时就会执行。这个函数是给类利用class_addMethod添加函数的机会。

如果实现了添加函数代码则返回YES,未实现返回NO

4.消息转发

在消息转发之前有一次重定向的问题

- (id)forwardingTargetForSelector:(SEL)aSelector __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

流程到了这里,系统给了个将这个SEL转给其他对象的机会。

返回参数是一个对象,如果这个对象非nil、非self的话,系统会将运行的消息转发给这个对象执行。否则,继续下一步。

- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;

5.runtime方法

两个可能会会在这个流程需要的方法:

OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
OBJC_EXPORT IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)  __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

6.注解

①SEL:方法选择器,在objc.h的定义为:

typedef struct objc_selector *SEL;

所以SEL是char*指针,代表它的方法名称

②IMP:函数指针

7.推荐

https://github.com/nicklockwood/NullSafe

8.感谢

Sam_Lau的Objective-C特性:Runtime

玉令天下博客的Objective-C Runtime

顾鹏博客的Objective-C Runtime

wangzz的Objective-C runtime


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值