NSObject 上的类别——保证其安全
苹果有这样说:
根类的类别
类别可以向任何类添加方法,包括根类。添加到 NSObject 的方法可供链接到您的代码的所有类使用。使用类别向根类添加方法有时很有用,但也可能非常危险。虽然类别所做的修改似乎很容易理解并且影响有限,但继承赋予了它们广泛的范围。您可能对应用程序中看不见的类进行了无意的更改;你可能不知道你正在做的事情的所有后果。此外,处理您的应用程序的其他人不知道您的更改,也不会理解他们在做什么。
我的问题是——如果我选择的方法名称足够奇怪,我确信不会其他人会使用它们(无论是在 Apple 还是在我的项目中),我还会遇到麻烦吗?还会有意想不到的行为吗?性能影响?
Apple has this to say:
Categories of the Root Class
A category can add methods to any class, including the root class. Methods added to NSObject become available to all classes that are linked to your code. Adding methods to the root class with a category can be useful at times, but it can also be quite dangerous. Although it may seem that the modifications the category makes are well understood and of limited impact, inheritance gives them a wide scope. You may be making unintended changes to unseen classes in your application; you may not know all the consequences of what you’re doing. Moreover, others working on your application, who are unaware of your changes, won’t understand what they’re doing.
My question is -- if I choose method names that are sufficiently weird that I am quite sure that no one else will use them (either at Apple or in my project), can I still get into trouble? Could there still be unexpected behavior? Performance implications?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您确实非常确定 Apple 永远不会添加该名称的方法,那么这是安全的。如果您想强制这种确定性,请为选择器名称添加前缀。例如,Adium 曾经向
NSMutableArray
添加了一个-setObject:atIndex:
方法(是的,只是现有 API 方法-replaceObject 的“装饰”包装器) :atIndex
。非常没有意义)...结果与内部方法具有相同的名称,并且语义略有不同。这会导致崩溃,但仅限于某些操作系统。如果它被命名为类似-AISetObject:atIndex:
就可以了。对类别的性能影响很小。我不会担心这方面。
If you're really quite certain that Apple would never add a method of that name, it's safe. If you want to enforce that certainty though, prefix the selector name. For example, Adium at one point added a
-setObject:atIndex:
method toNSMutableArray
(yes, just a "cosmetic" wrapper over the existing API method-replaceObject:atIndex
. Very pointless)... it turned out to have the same name as an internal method, and veeeeery slightly different semantics. This caused crashes, but only on certain OSs. If it had been named something like-AISetObject:atIndex:
it would have been fine.Performance implications for categories are minimal. I wouldn't worry about that aspect.
如果您的方法名称不与任何内容冲突,并且使用它们的人知道它们的作用,那么您应该不会遇到任何问题。请记住,类别会向类添加额外的方法,但不会添加实例变量。子类更加灵活,并且被视为整个对象,它响应所有超类方法以及它自己的方法。我会说创建一个子类,除非你不能或者这样做不方便。毕竟,类别是为了使用而设计的。当我有一个框架并且需要将私有方法添加到公开声明的类中时,我通常使用类别。
If your method names do not conflict with anything, and people who use them know what they do, you shouldn't run into any problems. Remember, a category adds extra methods, but not instance variables to a class. A subclass is more flexible, and is treated as an entire object, which responds to all superclass methods plus it's own. I would say make a subclass unless you can't or it's inconvenient to do so. Categories were made to be used, after all. I usually use categories when I have a framework and I need to add private methods to a publicly declared class.