首页 > 代码库 > 第25条:总是为第三方类的分类名称加前缀
第25条:总是为第三方类的分类名称加前缀
本条要点:(作者总结)
分类机制通常用于向无源码的既有类中新增功能。这个特性极为强大,但在使用时也很容易忽视其中可能产生的问题。这个问题在于:分类中的方法是直接添加在类里面的。它们就好比这个类中的固有方法。将分类方法加入类中这一操作是在运行期系统加载分类时完成的。运行期系统会把分类中所实现的每个方法都加入类的方法列表中。如果类中本来就有此方法,而分类又实现了一次,那么分类中的方法会覆盖原来那一份实现代码。实际上可能会发生很多次覆盖,比如某个分类中的方法覆盖了 “主实现” 中的相关方法,而另外一个分类中的方法又覆盖了这个分类中的方法。多次覆盖的结果以最后一个分类为准。
比方说,要给NSString 添加分类,并在其中提供一些辅助方法,用于处理与 HTTP URL 有关的字符串。你可能会把分类写成这样:
1 @interface NSString (HTTP) 2 3 // Encode a string with URL encoding 4 - (NSString *)urlEncodedString; 5 6 // Decode a URL encoded string 7 - (NSString *)urlDecodedString; 8 9 @end
现在看起来没什么问题,可是,如果还有一个分类也往 NSString 里面添加方法,那会如何呢?那个分类里可能也有个名叫 urlEncodedString 的方法,其代码与你所添加的大同小异,但却不能正确实现你所需的功能。那个分类的加载时机如果晚于你所写的这个分类,那么其代码就会把你的那一份覆盖掉,这样的话,你在代码中调用 urlEncodedString 方法时,实际执行的是那个分类里的实现代码。由于其执行结果和你预期的值不同,所以自己所写的那些代码也许就无法正常运行了。这种bug 很难追查,因为你可能意识不到实际执行的 urlEncodedString 代码并不是自己实现的那一份。
要解决此问题。一般的做法是: 以命名空间来区别各个分类的名称与其中所定义的方法。想在 Objective-C 中实现命名空间功能,只有一个办法,就是给相关名称都加上某个共用的前缀。与类名加前缀时所应考虑的因素相似
第25条:总是为第三方类的分类名称加前缀