Runtime2

来源:互联网 发布:阿里云服务器挂载 编辑:程序博客网 时间:2024/05/03 22:34

1 类型编码

编译器将每个方法的返回值和参数类型编码作为一个字符串


2 关联对象

我们不能在分类中添加成员变量

解决方案:关联对象

当宿主对象被释放时,会根据指定的内存管理策略来处理关联对象

内存管理策略是retain关联对象,当宿主对象释放时,会自动release关联对象, 如果我们使用同一个key来关联另一个对象时,也会自动释放之前关联的对象


3 SEL又叫选择器,是表示一个方法的selector的指针

Objective-C在编译时, 会依据每一个方法的名字,参数序列,生成一个唯一的整型标识,这个标识就是SEL


4 IMP实际上是一个函数指针, 指向方法实现的首地址

id(*IMP)(id,SEL,...) 第一个参数self指针, 如果是实例方法,则是类实例的内存地址;如果是类方法,则指向元类的指针.第二个参数是方法选择器,接下来是方法的参数列表


5 方法的调用流程

objc_msgSend 通过isa指针获得类的结构体, 然后在方法分发列表里查找方法的selector, 如果没有找到,向父类查找, 如果最后没找到, 会走消息转发流程


6 消息转发

动态方法解析

备用接收者

完整转发


动态方法解析: 我们已经实现了该处理方法, 只需要在运行时通过class_addMethod函数动态添加到类里面就可以了

备用接收者: 这一步适合于我们只想将消息转发到另一个能处理该消息的对象上

完整消息转发:

- (void)forwardInvocation:(NSInvocation *)anInvocation

把与尚未处理的消息有关的全部细节都封装在anInvocation中, 包括selector, target, 和参数

我们必须重写

 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
消息转发机制使用从这个方法中获取的信息来创建NSInvocation对象, 因此我们必须重写这个方法,为指定的selector提供一个合适的方法签名


7. Method Swizzling

Swizzling应该总是在+load中执行

+load会在类初始化加载时候调用

+initialize会在第一次调用类的类方法或实例方法之前调用

Swizzling应该总是在dispatch_once中执行, 它确保代码只被执行一次, 不管多少个线程


8 协议与分类

协议一旦注册后就不可再修改


9 super

self是类的一个隐藏参数, super只是一个编译器标示符


0 0
原创粉丝点击