底层-Runtime

2020-01-09  本文已影响0人  Stago

isa详解

isa详解 – 位域

  • 0,代表普通的指针,存储着Class、Meta-Class对象的内存地址
  • 1,代表优化过,使用位域存储更多的信息

是否有设置过关联对象,如果没有,释放时会更快

是否有C++的析构函数(.cxx_destruct),如果没有,释放时会更快

存储着Class、Meta-Class对象的内存地址信息

用于在调试时分辨对象是否未完成初始化

是否有被弱引用指向过,如果没有,释放时会更快

对象是否正在释放

里面存储的值是引用计数器减1

  • 引用计数器是否过大无法存储在isa中
  • 如果为1,那么引用计数会存储在一个叫SideTable的类的属性中

Class的结构

class_rw_t

class_ro_t

method_t

  • 可以通过@selector()和sel_registerName()获得
  • 可以通过sel_getName()和NSStringFromSelector()转成字符串
  • 不同类中相同名字的方法,所对应的方法选择器是相同的

Type Encoding

方法缓存

  • objc-cache.mm
bucket_t * cache_t::find(cache_key_t k, id receiver)

objc_msgSend执行流程

  • 消息发送
  • 动态方法解析
  • 消息转发

objc_msgSend执行流程 – 源码跟读

  • ENTRY _objc_msgSend
  • b.le LNilOrTagged
  • CacheLookup NORMAL
  • .macro CacheLookup
  • .macro CheckMiss
  • STATIC_ENTRY __objc_msgSend_uncached
  • .macro MethodTableLookup
  • __class_lookupMethodAndLoadCache3
  • _class_lookupMethodAndLoadCache3
  • lookUpImpOrForward
  • getMethodNoSuper_nolock、search_method_list、log_and_fill_cache
  • cache_getImp、log_and_fill_cache、getMethodNoSuper_nolock、log_and_fill_cache
  • _class_resolveInstanceMethod
  • _objc_msgForward_impcache
  • STATIC_ENTRY __objc_msgForward_impcache
  • ENTRY __objc_msgForward
  • forwarding(不开源)

objc_msgSend执行流程01-消息发送

  • 已经排序的,二分查找
  • 没有排序的,遍历查找

objc_msgSend执行流程02-动态方法解析

  • +resolveInstanceMethod:
  • +resolveClassMethod:

从receiverClass的cache中查找方法”这一步开始执行

动态添加方法

objc_msgSend的执行流程03-消息转发

生成NSMethodSignature


super的本质

  • struct objc_super2
  • SEL

LLVM的中间代码(IR)

clang -emit-llvm -S main.m

  • @ - 全局变量
  • % - 局部变量
  • alloca - 在当前执行的函数的堆栈帧中分配内存,当该函数返回到其调用者时,将自动释放内存
  • i32 - 32位4字节的整数
  • align - 对齐
  • load - 读出,store 写入
  • icmp - 两个整数值比较,返回布尔值
  • br - 选择分支,根据条件来转向label,不根据条件跳转的话类似 >- goto
  • label - 代码标签
  • call - 调用函数

Runtime的应用01 – 查看私有成员变量

Runtime的应用02 – 字典转模型

Runtime的应用02 – 替换方法实现

Runtime API01 – 类

Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
void objc_registerClassPair(Class cls) 
void objc_disposeClassPair(Class cls)
Class object_getClass(id obj)
Class object_setClass(id obj, Class cls)
BOOL object_isClass(id obj)
BOOL class_isMetaClass(Class cls)
Class class_getSuperclass(Class cls)

Runtime API02 – 成员变量

Ivar class_getInstanceVariable(Class cls, const char *name)
Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
void object_setIvar(id obj, Ivar ivar, id value)
id object_getIvar(id obj, Ivar ivar)
BOOL class_addIvar(Class cls, const char * name, size_t size, uint8_t alignment, const char * types)
const char *ivar_getName(Ivar v)
const char *ivar_getTypeEncoding(Ivar v)

Runtime API03 – 属性

objc_property_t class_getProperty(Class cls, const char *name)
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes,
                  unsigned int attributeCount)
void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes,
                      unsigned int attributeCount)
const char *property_getName(objc_property_t property)
const char *property_getAttributes(objc_property_t property)

Runtime API04 – 方法

Method class_getInstanceMethod(Class cls, SEL name)
Method class_getClassMethod(Class cls, SEL name)
IMP class_getMethodImplementation(Class cls, SEL name) 
IMP method_setImplementation(Method m, IMP imp)
void method_exchangeImplementations(Method m1, Method m2) 

Method *class_copyMethodList(Class cls, unsigned int *outCount)
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
SEL method_getName(Method m)
IMP method_getImplementation(Method m)
const char *method_getTypeEncoding(Method m)
unsigned int method_getNumberOfArguments(Method m)
char *method_copyReturnType(Method m)
char *method_copyArgumentType(Method m, unsigned int index)
const char *sel_getName(SEL sel)
SEL sel_registerName(const char *str)
IMP imp_implementationWithBlock(id block)
id imp_getBlock(IMP anImp)
BOOL imp_removeBlock(IMP anImp)
上一篇 下一篇

猜你喜欢

热点阅读