虽然我们知道这样写很丑, 但是我们应该要在我们的 category 方法前加上自己的小写前缀以及下划线,比如`- (id)zoc_myCategoryMethod`。 这种实践同样[被苹果推荐](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW4)。
这是非常必要的。因为如果在扩展的 category 或者其他 category 里面已经使用了同样的方法名,会导致不可预计的后果。实际上,实际被调用的是最后被实现的那个方法。
如果想要确认你的分类方法没有覆盖其他实现的话,可以把环境变量 OBJC_PRINT_REPLACED_METHODS 设置为 YES,这样那些被取代的方法名字会打印到 Console 中。现在 LLVM 5.1 不会为此发出任何警告和错误提示,所以自己小心不要在分类中重载方法。
一个好的实践是在 category 名中使用前缀。
** 例子 **
~~~
@interface NSDate (ZOCTimeExtensions)
- (NSString *)zoc_timeAgoShort;
@end
~~~
** 不要这样做 **
~~~
@interface NSDate (ZOCTimeExtensions)
- (NSString *)timeAgoShort;
@end
~~~
分类可以用来在头文件中定义一组功能相似的方法。这是在 Apple的 Framework 也很常见的一个实践(下面例子的取自`NSDate` 头)。我们也强烈建议在自己的代码中这样使用。
我们的经验是,创建一组分类对以后的重构十分有帮助。一个类的接口增加的时候,可能意味着你的类做了太多事情,违背了类的单一功能原则。
之前创造的方法分组可以用来更好地进行不同功能的表示,并且把类打破在更多自我包含的组成部分里。
~~~
@interface NSDate : NSObject <NSCopying, NSSecureCoding>
@property (readonly) NSTimeInterval timeIntervalSinceReferenceDate;
@end
@interface NSDate (NSDateCreation)
+ (instancetype)date;
+ (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;
+ (instancetype)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)ti;
+ (instancetype)dateWithTimeIntervalSince1970:(NSTimeInterval)secs;
+ (instancetype)dateWithTimeInterval:(NSTimeInterval)secsToBeAdded sinceDate:(NSDate *)date;
// ...
@end
~~~