Objective-C Runtime (二)

前篇的代码已经让我们感受到了runtime的诡异,现在让我们分析几行代码

//1.载入内存的时候调用
+ (void)load{

    /*2.单例代码块,保证代码块中的代码只运行一次*/
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        /*3.得到描述一个类的结构体地址 typedef struct*/ objc_class *Class
        Class class = [self class];

        /*4.得到两个 sel 其实就是函数指针入口,但是我感觉这里像是消息,就是一个标记(字符串),其值在一个类的结构描述中,是唯一的 */
        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(hehe:);

        /*5.得到实现方法的实例 地址 也就是存放在 这个class objc_method_list 方法列表中的地址,这里想当然 用 class 这个地址 加 标示地址,的地址*/
        Method originalMethod = class_getInstanceMethod(class , originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class , swizzledSelector);

        /*6.将一个方法添加到这个类的objc_method_list 也就是注册,SEL 是发送的消息,也就是objc_msgSend(object, @selector(message)); 试想一下 SEL 就是一个字符串,也就是 key, 那么 value 就是 swizzledMethod 执行的地址*/

        /* 添加到
            6.1.class (描述类的结构体首地址),

            6.2.SEL 表示唯一标示,

            6.3.IMP :函数指针,实现消息的方法, method_getImplementation(swizzledMethod) 是实现 swizzledMethod 这个方法的地址

            6.4.const char * 相信大家对  int main(int argc, char * argv[]) 这个都清楚吧, 描述参数 和返回值 类型
         */

        BOOL didAddMethod = class_addMethod(class , originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

        /*7 如果添加成功,那么就替换自身的消息,hehe:YES 就会执行 系统的 viewWillAppear*/
        if (didAddMethod) {
            class_replaceMethod(class , swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod) );

        /*8.如果添加没成功,那么就交换两个实现方法*/
        }else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }

    });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值