小编在做 iOS 开发过程中有时会遇到想要对现有的类添加新的方法,或者是覆盖替换原来方法情况。也在有的情况我们在类实现过程中想要隐藏一些方法和属性情况。
所以就对实现一些注意做下整理:
Category : 运行期决议
- 可以把类实现分在不同类中实现。这样做有几个优点:1)可以减少单个类的体积 2)可以把不同的功能放在不同的
Category进行实现 3)可以多人同时开发一个类 4)可以更具具体的需要实现Category加载等 - 可以添加私有方法
Extension : 编译器决议
- 可以添加不想要暴露的类私有方法
- 可以添加类属性和类实例变量
Category 和 Extension 对比
Category 和 Extension 区别
Category(类目)和Extension(类拓展)有很大的区别。
Category 在运行期决定,不能对其进行添加实例变量(因为在编译器已经决定当前内存结构,如果可以添加实例变量就会造成当前类布局改变)。但是可以对现有的类进行添加类目。SDWebImage 中就有大量的使用。Extension 可以看作是没有名字的 Category,但是两者还是由本质的区别。Extension 是在编译器就已经决定的,而且和 interface 、 implement 共同组成类的一部分,三者同时在编译器决定并且一起消亡。所以对 iOS 中已经存在的实现类不能进行添加 Estension 的拓展。注:主要作用是隐藏类的一些相关信息。参考
Category 和 Extension 具体实现
1)Category 的实现
下面是对 NSString 添加类目,下面以 NSString+Configuration 类目展示:
NSString+Configuration.h
1 |
|
NSString+Configuration.m实现文件
1 |
|
2)Extension 的具体实现,下面以 Person类:
Person.h 文件
1 |
|
Person.m文件
1 | @interface Person () |
Category 真面目
如果对 runtime 有所了解,可以知道 OC 的很多是在 struct 的基础上完成的。 Category_t 在 struct 的结构上如下(在objc_runtime_new.h中):
1 | struct category_t { |
由上面可以看出:
Category里面可以添加实例方法、类方法、协议和类属性。
注释:
在
Category中添加的方法会放在原来类方法的前面,在调用方法过程中会调用前面方法,就会形成被类被覆盖的现象。原因是在调用类的过程中寻找调用方法是从上到下类进行查找的。
调用 Category 覆盖的方法
在 Category 覆盖的方法,是在查找过程中由于调用前面的方法而造成相关方法的覆盖。我们可以在调用前把 Category 的方法跳过。
具体实现如下:
1 | Class currentClass = [Person class]; |
Category 添加关联对象
Category 中不能添加类的变量。但我们通常需要添加关联对象的值,可以实现关联对象来进行实现。
Person+Habit.h文件:
1 | @interface Person (Habit) |
Person+Habit.m文件:
1 |
|
参考资料:
runtime
Category
Customizing Existing Classes
深入理解Objective-C
深入浅出理解分类(category)和类扩展(extension)