分类、继承、扩展

==分类==

是不能添加属性的,只能关联属性。
属性包含 get,set ,成员变量,而分类里并没有可存储成员变量的地址。所以即使声明了属性,也找不到地址。

分类是不能添加属性的,只能关联属性。
是在在类中用二维数组维护。
当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只会调用一次
在初始化的时候,如果在分类中重写了+initialize方法,则会覆盖掉父类的

==继承==
继承的好处:

简单直接,关系在编译时定义,被复用的实现易于修改。
继承的缺点:

  • 1:因为在编译时定义,无法运行时变更实现
  • 2:子类直接修改父类的实现,破坏封装性。
  • 3:父类的任何变更都可能引起子类的变更,因为实现在编译时绑定在一起了。
  • 4:可能新的场景不适用,那么必须要重写父类或者子类的实现。必须继承的情况下可解决办法是,只从协议或抽象基类继承,因为协议没有实现。
==extension==

extension看起来很像一个匿名的category,但是extension和有名字的category几乎完全是两个东西。

  • extension在编译期决议,它就是类的一部分,在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,它伴随类的产生而产生,亦随之一起消亡。
  • extension一般用来隐藏类的私有信息,你必须有一个类的源码才能为一个类添加extension,所以你无法为系统的类比如NSString添加extension。但是category则完全不一样,它是在运行期决议的。
==category和extension的区别==

extension可以添加实例变量,而category是无法添加实例变量的(因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的)。

==Category 为什么会替换掉原类的方法==

Runtime源码中记录了调用顺序

-objc_init
···
->remethodizeClass//重置类的方法
->attachCategories//绑定分类
->attachLists
->最核心的函数memmove和memcopy
  • memmove:将原来类中的信息列表在内存中向后移动,移动的大小就是分类中的信息所占大小
  • memcopy:将分类中的信息复制到上一步移动出来的空间。

所以系统是在运行时将分类中对应的实例方法、类方法等插入到了原来类或元类的方法列表中,且是在列表的前边

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容