美文网首页
Runtime触探学习笔记第一篇

Runtime触探学习笔记第一篇

作者: _Luyouli | 来源:发表于2020-08-21 15:58 被阅读0次

Runtime触探学习笔记

  • runtime是一套API,由C和C++汇编一起写成的API,给我们的OC提供运行时.

运行时

  • 运行时,代码在起来后装载内存,运行时功能就依赖于runtime

编译时

  • 正在编译的时间,编译过程的主要工作就是将源代码翻译成可以识别的语言,我们使用的比如OC,Swift,java等属于高级语言,需要翻译成机器语言(最底层的二进制)

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

  • OC的面向对象都是基于C/C++的结构体来实现的,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;
}
  • (void *)objc_msgSend)((id)person 消息接收者
  • sel_registerName("run")) 方法编号
  • imp函数实现的指针 ---sel -> imp 如何进行下层通讯
方法下层消息如何走的?对象方法和类方法分别是如何发起的?父类发送消息?
  • runtime的三种调用方式
    1.api
    2.NSObject (isKindOf)
    3.OC上层(@selector)

对象发送消息

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 发送消息的两种方式
  • 快速:直接通过汇编中的缓存cache_t(imp哈希表)中去找,每一个类中都会缓存
  • 慢速:直接通过C/C++ 汇编一起完成的,找到后又存在缓存中
  • 为什么objc_msgSend要用汇编写是因为C语言写一个函数无法通过保留未知的参数跳转到任意的一个指针。第二个原因就是更快。

相关文章

网友评论

      本文标题:Runtime触探学习笔记第一篇

      本文链接:https://www.haomeiwen.com/subject/ghoujktx.html