Catagory添加属性、扩展方法
objc_setAssociatedObject(self, &strKey, isShow, OBJC_ASSOCIATION_COPY_NONATOMIC);
return objc_getAssociatedObject(self, &strKey);
1、什么是Category?
category是Objective-C 2.0之后添加的语言特性,别人口中的分类、类别其实都是指的category。category的主要作用是为已经存在的类添加方法。除此之外,apple还推荐了category的另外两个使用场景。
可以把类的实现分开在几个不同的文件里面。这样做有几个显而易见的好处。
-
可以减少单个文件的体积
-
可以把不同的功能组织到不同的category里
-
可以由多个开发者共同完成一个类
-
可以按需加载想要的category
-
声明私有方法
apple 的SDK中就大面积的使用了category这一特性。比如UIKit中的UIView。apple把不同的功能API进行了分类,这些分类包括UIViewGeometry、UIViewHierarchy、UIViewRendering等。
不过除了apple推荐的使用场景,广大开发者脑洞大开,还衍生出了category的其他几个使用场景:
-
模拟多继承(另外可以模拟多继承的还有protocol)
-
把framework的私有方法公开
2、category特点
-
category只能给某个已有的类扩充方法,不能扩充成员变量。
-
category中也可以添加属性,只不过@property只会生成setter和getter的声明,不会生成setter和getter的实现以及成员变量。
-
如果category中的方法和类中原有方法同名,运行时会优先调用category中的方法。也就是,category中的方法会覆盖掉类中原有的方法。所以开发中尽量保证不要让分类中的方法和原有类中的方法名相同。避免出现这种情况的解决方案是给分类的方法名统一添加前缀。比如category_。
-
如果多个category中存在同名的方法,运行时到底调用哪个方法由编译器决定,最后一个参与编译的方法会被调用。
注意事项
- Category 可以访问原始类的实例变量,但不能添加变量,只能添加方法,如果想添加变量,可以考虑通过继承和创建子类
- Category 可以实现原始类的方法,但不推荐这么做,因为它是直接替换掉原来的方法,这么做的后果是再也不能访问原来的方法
- 多个 Category 中如果实现了相同的方法,只有最后一个参与编译的才会有效
- 方法调用的优先级:分类(最后参与编译的分类优先) –> 原来类 –> 父类