Runtime触探学习笔记第一篇

2020-08-21  本文已影响0人  _Luyouli

Runtime触探学习笔记

运行时

编译时

1.首先我们要从OC对象的本质开始

typedef struct objc_object SYPerson;
typedef struct {} _objc_exc_SYPerson;

struct SYPerson_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
};
objc_msgSend(s,sel_registerName("run"));

对于C函数而言就是静态性,如果我编译一个不存在的run函数就会直接报错,但是OC在编译阶段并不会报错,只会在运行时报错。比如在一个person对象中的.m文件中并没有实现run方法,但是在编译阶段不会错误,一旦运行后就会崩溃

clang使用方式

clang -rewrite-objc main.m -o main.cpp

clang运行项目main会生成一个cpp文件,cpp文件中有下面这段关键代码

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        SYPerson *person = ((SYPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((SYPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("SYPerson"), sel_registerName("alloc")), sel_registerName("init"));
        ((void (*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("run"));
        run();

    }
    return 0;
}
方法下层消息如何走的?对象方法和类方法分别是如何发起的?父类发送消息?

对象发送消息

SYPerson *me = [SYPerson new];
[me run];
((void (*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("run"));

类方法在元类中以实例方法的姿态存在,类在元类中也是以实例存在

id cls = [SYDog class];
void *pointA = &cls;
[(__bridge id)pointA walk];
((void (*)(id, SEL))(void *)objc_msgSend)(objc_getClass("SYDog"), sel_registerName("walk"));
 
objc_msgSend 发送消息的两种方式
上一篇 下一篇

猜你喜欢

热点阅读