iOS底层原理之分类的加载

前言

咱们在上一篇iOS底层原理之类的加载中探索了关于类的加载,在结尾部分咱们也注意到了处理分类的代码,此次咱们研究下分类的加载。markdown

分类的本质

研究分类的加载,咱们先看下分类的本质。函数

经过源码探究分类本质

咱们在源码中搜索category_t,搜索结果以下从上面咱们能够获得分类的本质是category_t结构体,结构体里面有namecls实例方法列表类方法列表协议列表属性列表类属性列表元类等信息,其中正由于分类中有属性列表,因此分类才能够动态添加 属性分类只能声明属性,因为没有set、get方法,因此须要动态添加)。post

分类的加载

咱们以LGPerson为主类,咱们添加LGPerson+LGALGPerson+LGB两个分类。 咱们从上一篇类的加载中得知最终会经过realizeClassWithoutSwift函数将类的信息关联起来,而realizeClassWithoutSwift函数经过methodizeClass函数来处理分类。spa

methodizeClass函数分析

methodizeClass函数中咱们能够看到最终是经过attachToClass函数来将分类添加到主类上的。3d

attachToClass函数

咱们查看attachToClass函数代码从中能够看到attachToClass函数最终又调用了attachCategories函数code

attachCategories函数

这个函数里面处理了分类的方法、属性、协议等。orm

分类加载反推路径分析

  • 咱们将断点打在attachCategories函数中的LGPerson判断部分,运行代码到断点位置,打印堆栈信息经过上图咱们能够发现实际上分类加载反推路径attachCategoriyes -> load_categories_nolock(执行两次) -> loadAllCategories -> load_images

分类加载正反推路径总结

主类分类混合加载

主类跟分类混合加载主要区分在是不是懒加载类,便是否实现了+load函数get

懒加载类与懒加载分类混合

咱们在main函数中打下断点,如图所示咱们发现此时仅仅执行了readClsss函数,经过咱们前面dyld与objc的关联咱们知道,这个readClass函数在编译阶段就会执行,所以得知此时并无加载类和其分类。咱们继续执行代码到NSLog处,此时咱们发现已经加载了类和其分类,所以咱们能够总结出来:懒加载类与懒加载分类混合,加载实际推迟到第一次消息转发时,即本文中的[LGPerson alloc]时源码

非懒加载类与懒加载分类混合

仍是同懒加载类与懒加载分类混合分析相同,从图中咱们发现还有执行[LGPerson alloc]时,类已经被加载了,即在编译阶段就已经被加载了it

非懒加载类与非懒加载分类混合

从上图中咱们得知也是在编译阶段加载了,只是在attachToClass函数中执行了两次load_categories_nolock函数

懒加载类与分懒加载分类混合

从上图中得知懒加载类与分懒加载分类混合时,会迫使主类在编译阶段加载

总结

相关文章
相关标签/搜索