==分类==
是不能添加属性的,只能关联属性。
属性包含 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:将分类中的信息复制到上一步移动出来的空间。
所以系统是在运行时将分类中对应的实例方法、类方法等插入到了原来类或元类的方法列表中,且是在列表的前边