NSObject的类别 - 保持其安全性

10

苹果公司在这里提到:

根类别

一个类别可以向任何类添加方法,包括根类。添加到NSObject的方法对于所有链接到您代码的类都可用。使用类别将方法添加到根类有时可能很有用,但也可能非常危险。尽管该类别所做的修改似乎被充分理解并且影响有限,但继承使它们具有广泛的范围。您可能会对应用程序中看不见的类进行意外更改;您可能不知道您所做的一切后果。此外,您的应用程序上工作的其他人员可能不了解您的更改,他们不会理解自己在做什么。

我的问题是,如果我选择足够奇怪的方法名称,以至于我确信没有人(无论是在苹果还是在我的项目中)会使用它们,我还能遇到麻烦吗?还可能出现意想不到的行为吗?会有性能方面的影响吗?


5
Objective-C 更倾向于使用子类化。但是,安全第一的做法难道不是属于失败者吗?;) - Patrick Perini
2个回答

9
如果你非常确定苹果不会添加那个名称的方法,那么就是安全的。但如果你想要确保这一点,可以在选择器名称前加上前缀。例如,Adium 曾经向 NSMutableArray 添加了一个“-setObject:atIndex:”方法(只是对现有 API 方法“-replaceObject:atIndex”的“装饰”),这完全没有意义……结果发现它与一个内部方法具有相同的名称,而且语义略有不同。这导致了崩溃,但仅在某些操作系统上。如果它被命名为类似“-AISetObject:atIndex:”这样的名称,就没问题了。
分类对性能的影响很小,所以不必担心这个方面。

3
不仅是系统的问题。一个崩溃报告在类别方法-[NSDictionary setDoubleValue:forKey:]中,结果发现与一个输入管理器冲突,该管理器实现了同名方法,但显然期望 Double 参数作为对象。该输入管理器被用于向 iChat 注入代码,但显然将完整的黑客加载到了包括其基础类别在内的每个应用程序中。 - Jens Ayton
我猜AISetObject不再很“美观”了 :-) - Joris Weimar

1

如果您的方法名称不会与其他内容冲突,并且使用它们的人知道它们的作用,那么就不应该遇到任何问题。记住,类别会添加额外的方法,但是对类而言并不会添加实例变量。子类更加灵活,并被视为整个对象,响应所有超类方法以及自己的方法。我建议除非不能或者不方便,否则都应该创建子类。毕竟,类别是用来使用的。当我需要向公开声明的类中添加私有方法时,通常使用类别。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接