例如,我将UILabel
子类化,并添加了一个名为-verticalTextAlignment
的方法或属性,以便垂直对齐文字。
并且在将来,如果下一版本的SDK或iOS添加了具有相同名称的方法或属性,则可能是我的应用程序崩溃或意外行为。
*即使您使用类别而不是子类化,也会出现此问题。
问题1
如何避免Objective-C中的这种意外覆盖?
我认为您可以通过为-XXX_verticalTextAlignment
之类的所有方法和属性添加前缀来避免这种情况。但这不现实,是吗?
问题2
我知道在编译时或更新iOS SDK,OSX SDK或XCode时会发生这种意外覆盖。
但是在更新iPhone的iOS版本时是否也有可能发生?
例如,您的应用程序是否可能在iOS5上运行良好但由于iOS6中的意外覆盖而无法在iOS6上运行。(您可以将iOS5和iOS6替换为任何版本,例如iOS5.0和iOS5.1) />
答案 0 :(得分:5)
是的,你可以使用你自己的前缀,但这种情况并不常见。
是的,可能在O / S更新后发生; Objective-C是一种非常动态的语言,其中消息被发送到方法而不是被调用,就像在其他语言中一样。这些东西在运行时完成,而不是编译时。
底线是肯定的,您可能会意外地覆盖未来的基类方法,唯一的解决方案就是在它发生时并重命名该方法。
答案 1 :(得分:1)
在每个不断增长的非命名空间的可可生态系统中,前缀类别方法是避免这些冲突的最安全方法。
框架创建者,开源开发人员和其他个人开发人员应该为他们的类方法添加前缀,这是非常有效和合理的。
我经常编写以公司名字缩写为前缀的方法,然后继续使用该方法。
- (void)JCMyMethodNamedSimilarToBaseClass;
答案 2 :(得分:1)
问题1a类别
使用前缀,或避免整个混乱并使用函数。
问题1b子类方法
如果一个方法做得足够通用,超类也可以实现它,我只需选择一个比Apple常规选择的方法名称更加“罗嗦” - 比如在方法名称中指定一个非标准的typename 。当然,这只是减少了碰撞的可能性。
如果你需要更高级别的安全性,你可以在执行时测试它(所以你知道它们何时被引入)并希望每个用户保持最新 - 或者你可以更加依赖C和/或C ++ (他们没有这个问题)。
问题2
但是在更新iPhone的iOS版本时是否也有可能发生?
是。这并不是那么不寻常。当框架更新时(例如通过软件更新),它们可能包含更新的框架。此代码被加载到objc运行时,您始终可以获得已安装框架的objc实现的版本。
这也是OS X上一个更广泛的问题,你可以很容易地动态加载代码和/或插件。
答案 3 :(得分:1)
一个优雅的解决方案是检查已经存在的方法,如果不存在则只添加它:Conditional categories in Mountain Lion