Category 与 Extension
2017-07-05 本文已影响57人
Randall_Steven
Category(分类)
我们为什么要用Category
当我们需要为已知的类添加方法的时候,我们就可以考虑使用Category。有人就会问,为什么我们不直接在这个类中添加方法,或者继承这个类在子类中添加方法?
首先,不直接在这个类中添加方法的原因,一种情况是我们可能没有办法直接修改这个类的文件,例如给NSArray添加一个方法,我们只能写一个Category。还有就是如果我们修改了这个类的方法,那么他的子类也都会受到影响,所以这并不是一个好的做法
再说继承,我们加了这个方法之后,这个类从设计上讲还是这个类,而不是他的子类,所以继承并不是很合理
如何写一个Category
- Objective-C
@interface NSObject (Category)
- (void)myMethod;
@end
@implement NSObject (Category)
- (void)myMethod {
/*方法实现*/
}
@end
需要留意的地方
- Category中添加的方法尽量不要与原有类中方法重名,虽然实现上是可以这样做的,但这个绝对不是一个很好的设计。因为当你添加类重名方法之后,那么就没有办法在访问原有方法,而且降低了代码的可读性。如果需要添加一个重名方法,建议还是用继承的方式,在子类中覆写这个方法。(Demo中有相关测试代码)
- 我们不能直接通过Category来给类添加属性,因为Category不会为我们的属性添加get和set方法,所以在调用的时候就会崩溃,但是我们可以利用runtime来添加些方法
Extension
看起来像是一个匿名的Category,但是二者还是有很多区别的。Extension通常写在.m文件中,当我们新建一个view controller子类的时候,我们可以在.m文件中看到系统会为我们自动生产一个Extension,而我们在新建一个NSObject的子类的时候,系统就不会自动为我们创建这个Extension
Extension是声明类中私有方法的好方法
如何写一个Extension
- Objective-C
@interface NSObject ()
- (void)myMethod;
@end
二者区别
- 对于有些情况我们就没法去使用Extension,我们只有在可以编辑这个类的源码的时候,我们才可以添加Extension,例如我们没有办法给NSString添加Extension
- Extension是可以添加@property的,而Category则需要runtime才能实现添加@property
- Extension中方法声明之后必须在这个文件中的@implement中实现(否则不实现也没什么用,是吧),Category可以在这个类的任何一个地方,哪怕是父类中实现就可以。
Demo
具体上面的内容我写了个小Demo,大家可以下载下来看看,有些代码注释掉了(主要是我不想在项目中有warning),可以把注释去了,看看这些情况,实际执行的哪个方法,对理解有很大帮助。
还有就是很推荐大家看看下面美团点评团队的这个博客,很深入的讲解了Category,很涨知识