Category支持添加属性与成员变量吗

文章目录
[隐藏]

1. Category 简介:

作用:
    1.可以将类的实现分散到多个不同文件或多个不同框架中,方便代码管理。
        也可以对框架提供类的扩展(因为框架类没有源码,不能修改)。
    2.创建对私有方法的前向引用:如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错,这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告。
    3.向对象添加非正式协议:创建一个NSObject的类别称为“创建一个非正式协议”,
    因为可以作为任何类的委托对象使用。
局限性:
    1.无法向类中添加新的实例变量,类别没有位置容纳实例变量。
    2.名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。
    类别方法将完全取代初始方法从而无法再使用初始方法。这个类似于方法的重载,但是这里是直接覆盖了原方法。

2.Category添加成员变量和属性

2.1.添加成员变量

1.首先 在Category中添加成员变量 直接报错
2.为什么不能添加? 
    因为Category原理是:通过运行时把Category的方法添加到类实例中,所以Category是运行时的生成的。
    而运行时,对象的内存布局已经确定(成员变量属于类实例,所谓“类实例”是指一块内存区域,包含了isa指针和所有成员变量)。
    如果添加成员变量就会破坏类的内部结构,使类实例变成无效实例。所以Category不能添加成员变量

2.2.添加属性

1.属性可以利用runtime来关联对象。
2.所有的关联对象都有AssociationsManager来管理。
(AssociationsManager:由一个静态AssociationsHashMap来存储所有的关联对象,key是这个对象的指针地址,value是另一个AssociationsHashMap,保存着关联对象的key/value)
3.关联属性:objc_setAssociatedObject(self,
                                    "name",
                                     name,
                                     OBJC_ASSOCIATION_COPY);
  获取属性:NSString *name = objc_getAssociatedObject(self, "name");
  销毁属性:runtime在销毁对象实例时候,objc_destructInstance会判断这个对象有没有关联对象,如果有 会调用_object_remove_assocations 来做关联对象清理工作。

总结:
1.category可以利用runtime实现添加属性的功能。但不能添加成员变量

参考:

https://tech.meituan.com/DiveIntoCategory.html

http://quotation.github.io/objc/2015/05/21/objc-runtime-ivar-access.html

182 人浏览过

发表评论

邮箱地址不会被公开。 必填项已用*标注