美文网首页iOS专题
runtime 框架整理

runtime 框架整理

作者: 没有格子衫 | 来源:发表于2019-11-27 21:08 被阅读0次

runtime初探

runtime

C C++ 汇编写成的API
OC 运行时

  • legacy Version

早期版本Objctive-C 1.0 中32位的Mac OSX的平台

  • Mordern Version

    • 2.0 objc源码750

    • Mac OS X V10.5以后的64系统

源码解析

id objc_msgSend(id self, SEL, _cmd,...)

汇编跟进来

ENTRY _objc_msgSend

  • 1,如果指针小于LNilOrTagged 直接return返回

  • 2,通过isa找到响应类class

  • 3,CacheLookup 找我们一般参数:NORMAL

  • CacheLookup 是个宏定义

    • 1,CacheHit $0

      • 1,NORMAL MESSENGER_END_FAST 结束查找路径

      • 2,GETIMP 直接返回对应参数就OK

      • 3,LOOKUP

    • 2,CheckMiss $0 就是找不到系列

      • 1,GETIMP ---- LGetImpMiss

      • 2,NORMAL ---- __objc_msgSend_uncached

        • 就是说没有响应的缓存

        • 接下来去 MethodTableLookup 方法列表查找

        • __class_lookupMethodAndLoadCache3 汇编查找

        • _class_lookupMethodAndLoadCache3 C函数

          lookUpImpOrForward(cls, sel, obj, YES/*Initiailze*/, NO/*cache*/ 因为我们查找了没有 就没有必要传参cache,YES/*resclver*/)

          • imp = cache_getImp(cls,sel);----CacheLookup

          • 接下来都是一些判断配置

          • 核心:retry

            • cache_getImp 又去拿一次 因为OC动态语言,随时随地的都能操作修改,防止数据问题,再取一次。

            • 1,getMethodNoSuper_nolock 从自己类的方法方法列表去找 --- 如果找到了就去填充到缓存。

            • 2,cls -> superclass,cache_getImp(curClass, sel)从递归父类去找,直到NSObject

          • 如果还没有找到:No Implementation found. Try method resolver once.

        • 3,LOOKUP __objc_msgLookup_uncached

          • 3: add

            • 1,CacheHit

            • 2,CheckMiss

            • 3,JumpMiss

注意跟对架构 objc-msg-arm64.s

runtime 三种调用方式

  • runtime api

(class_ ,objc_ .....)

  • NSObject

(isKindOf:,isClassOf:......)

  • 编译器提供的 OC上层方法:@selector

objc_msgSend 发送消息

  • 两种方式:

    • 快速 -> 汇编 -> 缓存中找到 imp 哈希表
      缓存 cache_t 中找,

    • 慢速 -> C, C++, 汇编 -> 缓存

    • 复杂的过程

  • c 写一个函数,保留未知的参数,跳转到任意函数中去。

  • 汇编可以 寄存器 x0 x31

tagged pointer 特殊的数据类型

源码分析流程

1, 方法查找

汇编部分:
  • _objc_msgSend

  • LNilOrTagged

  • LGetLsaDone isa 处理完毕

  • Cache_Lookup NOEMAL 缓存中找imp

    • call imp

    • objc_msgSend_uncached

    • CacheHit -> CALL

    • CheckMiss -> _objc_msgSend_uncached -> MethodTableLookup

    • add

  • MethodTableLookup

  • bl __class_lookupMethodAndLoadCache3 -> C / C++

C / C++
  • lookUpImpOrForward

  • realizeClass(cls)

  • _class_initialize

  • 漫长过程 -> 找方法

    • 本类

    • 父类 -> getMethodNoSuper_nolock

    • NSObject

    • getMethodNoSuper_nolock -> log_and_fill_cache

    • log_and_fill_cache

2, 动态方法解析

  • lookup imp没有

    • __class_resolveMethod

      • __class_resolveInstanceMethod

      • __class_resolveClassMethod

    • 只有一次

3, 消息转发

  • forwardingTargetForSelector

    • 自定义处理

    • 防止崩溃

  • methodSignatureForSelector

  • forwardInvocation

    • 指定一个简单的异行的方法

    • 打印系统调用堆栈

    • 打印的东西存到沙盒 -> 服务器

    • AOP 切面编程,埋点统计

    作业:aspect -- 消息转发的源码

    • method-swizzing hook array 数组越界:

    [self.dataArray objcAtIndex ]
    if index < self.dataArray.count - 1 --excepetion

  • instrumentObjcMessageSends

    打印所有关于objc调用堆栈的一些信息

runtime 应用调用


runloop

KVC

KVO

运行时

代码 -- 编译连接 -- 执行

对于C函数就是静态性,编译如果不存在这个run函数,就会报错,但是OC 不一样。

OC代码run起来之后,会被装在进内存。不存在函数运行时不会报错,只有到调用的时候,如果不存在这个函数方法,OC才会报错。

  • OC 对象 -- 本质 -- 结构体

类方法 元类 -- 姿态 实例方法

对象 在 类 实例

类 在元类 实例

编译时

编译时,就是编译器把源代码翻译成机器能够识别的语言。

代码跑起来,被装填到内存中去。

OC swift java

高级语言,可读性较强,不会被机器所识别,需要转成机器语言汇编,最终会转换成二进制

OC对象

OC 对象 - 本质 -- 结构体

编译 clang

Person *p = [[Person alloc] init];
Person *p = ((Person ()(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("new"));

  • 方法调用 objc_msgSend
  • 方法的本质 --- 发送消息
  • 消息的组成

(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("run"));

  • (void *)objc_msgSend)((id)p) 消息的接受者
  • sel_registerName("run") 方法编号 -- name
  • imp 函数实现的指针 -- sel -> imp

下层通讯

方法 -- 对象 类

typedef struct objc_object LGPerson; 对象的本质就是结构体

每个对象的底层都有一个implist
struct LGPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS;
};

父类发送消息

相关文章

  • runtime 框架整理

    runtime初探 runtime C C++ 汇编写成的APIOC 运行时 legacy Version 早期版...

  • runtime-整理中

    runtime-整理中

  • Runtime整理

    runtime一致蒙着一层神秘的面纱,在面试中,90%的技术都会问道相关的问题,目的为了考察OC中学习的深度.这里...

  • Runtime 整理

    做iOS 的基本上没有有几个不知道Runtime的吧; 1.通过runtime 获取成员变量列表、属性列表、方法列...

  • class和superclass

    class和superclass源码(runtime源码里有) Foundation框架里NSObject框架里的...

  • RunTime 解析转发

    RunTime 整理的很清晰、到位

  • runtime 你看这里就够了

    最近在整理文档,看到一些关于runtime 的东西。想说整理一下给新手看看。 那什么是runtime 呢? Run...

  • iOS知识点整理

    iOS知识点整理 持续更新中。。。 runtime相关 iOS 模块详解—「Runtime面试、工作」看我就 ? ...

  • 《runtime篇isa指针,objc_msgSend函数执行流

    本文仅供自我学习笔记。参考《小码哥的runtime》教学。 终于有时间整理了,想整理的几个知识点都与runtime...

  • Runtime 见闻整理

    Runtime 基本是用C和汇编写的Runtime 涉及三个点,面向对象,消息分发,消息转发 面向对象 Objec...

网友评论

    本文标题:runtime 框架整理

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