iOS学习iOS性能优化相关iOS技术专题

runtime之类方法和实例方法

2017-11-18  本文已影响29人  lazy_boy_coder
scenery.png
在本文开始之前,先发表下个人见解。runtime是OC语言的特性,Method
Swizzling 是苹果针对runtime暴露的API接口。如果,你使用Method
Swizzling造成了一些的问题,那可能是你使用Method Swizzing
的姿势有些不太对。下一篇文章会对Method Swizzing 造成的问题,
以及为什么会造成这些问题做一个总结。下面先来说说本文标题的内容。

什么是类方法和实例方法?

1.从标识符角度考虑

在Objective-C中标识符 "-" 是实例方法,标识符"+"是类方法/静态方法。

2.从调用方式上考虑

实例方法的调用时需要实例对象,而类方法的调用则可以通过类直接调
用。

在runtime中

class-diagram.jpg
isa 指针指向

实例对象的isa指针指向该实例对象的类,类指向该类元类,元类有点特殊,统一指向根元类,根元类指向自己。

继承关系

类继承自己的父类,继承体系一直往上,最终指向nil,元类指向父元类,最终根元类,指向NSObject。

内存分配

指向实例化对象的指针,存储在栈区;实例化的Objective-C对象存储在堆区,类和元类存在在代码段。

实例方法的调用

对象方法的调用实际上是发送消息给这个对象,对象在接受到这个消息之后。首先,他会去方法缓存列表中根据SEL查找函数指针IMP,找到之后直接通过指针调用该函数。如果,没有找到就去方法列表methodlist中根据SEL查找函数指针IMP。找到后直接通过指针调用函数,并且把该方法放在缓存列表中,如果没找到那就沿着继承体系向上查找。如果,还是找不到该方法,那就执行消息转发。

类方法调用

首先我们知道类方法是保存在该类的元类中的,类在OC中,也可以看成是元类的一个实例。当类方法被调用的时候,元类首先会查找本身是否有该类方法的实现,如果没有该元类会向他的父元类继续查找该方法,一直找到继承链的头。类方法不会出现向实例方法找不到的情况。因为,如果不存在该类方法,那么在编译的时候都通不过。

关于实例方法和类方法的内存占用

实例方法

实例对象的创建被分配在堆区,该对象的内存管理完全交给了ARC去完成。实例方法只有在调用的时候才会分配内存,这个点可以通过Xcode自带的Instruments工具中Allocations来做测试,证明想法,楼主这里就不做演示。

类方法

类方法的调用不同于实例方法,下面来看一张图:


image.png

一个类可以有n个实例化对象,但是一个元类只有一个类实例,这个类的isa唯一指向元类。当App在启动的时候就已经为类方法分配了内存,而且贯穿整个app应用的生命周期。类方法的调用会常驻内存,不是被调用才会常驻内存,而是一直都会。

上一篇 下一篇

猜你喜欢

热点阅读