Category
自从category
被加入到Objective-C 2.0中以来,已经被开发者广泛应用到自己的App中.有了category
我们可以为各种类添加新的方法.category的强大能力来源于运行时.
代码分散
使用category有利于将代码进行分散管理.假设我们要实现一个功能强大的类,我们很可能会把这个类的所有代码都写在一个文件里.为了防止各种功能的代码随意分布在文件中,我们应该使用category把各个功能的代码分开.但是,如果把所有的分类都写在一个文件里,情况也不会变得很好.所以,正确的做法应该是将各个分类写在不同的文件中,便于管理.
1 | //MobilePhone+SMS.h |
添加前缀
可以预见,由于可以向系统的类添加分类,那么可能有数个分类拥有相同名称的方法.而一旦出现这种情况,最终调用的方法是最后被加载的分类所实现的方法.所以,普遍做法是为分类中的所有方法添加一个前缀.
添加属性?
虽然不能使用category向类中添加实例变量,但是我们可以使用category为类添加属性.
1 | //MobilePhone+sms.h |
然而,系统会发出警告,意思是无法合成与sms相关的实例变量,所以我们应该在分类中为期实现getter和setter,并且用@dynamic
修饰它.至于getter和setter,可以使用关联对象实现.但是要注意使用关联对象的各种问题.
1 | //MobilePhone+sms.m |
class-continuation分类
class-continuation分类
又被称为扩展(extension)
.class-continuation和普通的分类不同,它必须被定义在那个接受此分类的主实现文件
里.所以,因为没有各种系统类的实现文件,我们并不能向系统类添加这种分类.它可以向类添加实例变量和方法等.class-continuation分类
和类本身是一起编译的,所以它可以添加实例变量.
隐藏细节
使用class-continuation分类,我们可以将变量和方法的声明移到类的实现文件中,从接口文件中就找不到其声明了.
改变读写属性
有些属性在接口文件中被声明为只读
,但是如果在类内部需要设置该属性的值,怎么办呢?可以使用class-continuation分类扩展该属性为可读写
,在类内部中就可以使用其setter方法设置其值.使用这种方法比起在类中直接设置ivar的优势在于可以触发KVO
.
1 | //MobilePhone.h |
参考资料:
- In Objective-C, why class-continuation can add instance variables but class category can’t?
- Effective Objective-C 2.0