剖析运行时(让你看懂运行时)

16 篇文章 0 订阅
  • 运行时机制:比较高级的特性,纯C语言
  • 实际上我们平时写的OC代码,都是转成C语言的运行时代码,运行时代码的效率更高,更直接

Person.h

@interface Person : NSObject
@property(nonatomic,assign)int age;
@end

main.m

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [[Person alloc]init];

        p.age = 10;
    }
    return 0;
}

我们来窥探底层对我们的这两句代码做了什么事情:

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        Person *p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));

        ((void (*)(id, SEL, int))(void *)objc_msgSend)((id)p, sel_registerName("setAge:"), 10);
    }
    return 0;
}
  • 可能这样看起来有点乱,我稍微整理一下:
    alloc,init底层就是这样的:
id pp = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));

        Person *p = objc_msgSend(pp, sel_registerName("init"));

其实就是给Person这个类发送一个alloc消息,然后返回一个Person对象,再给Person这个对象,发送一个init消息,返回一个初始化完毕的对象。


我们继续看:

objc_msgSend(p, sel_registerName("setAge:"), 10);

这里是给Person对象发送一个setAge:消息,参数是10.


那么我们在main中的代码,我们其实也可以这么写:

#import "Person.h"
#import <objc/message.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [[Person alloc]init];

        objc_msgSend(p, @selector(setAge:),20);

        NSLog(@"%d",p.age);

//        p.age = 10;

    }
    return 0;
}

然而,这个可能你们还不能看出运行时有什么好处,具体的运行时的好处,看我之前写的博客:给运行时添加属性
运行时的常见三种用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值