13

例如,我子类化UILabel并添加了一个方法或属性,称为-verticalTextAlignment垂直对齐文本。
并且在未来,如果下一版本的 SDK 或 iOS 添加了同名的方法或属性,那么我的应用程序可能会崩溃或出现意外行为。

*即使您使用类别而不是子类化,也会发生此问题。

Question1
在Objective-C中如何避免这种意外覆盖?
我认为您可以通过为所有方法和属性添加前缀来避免这种情况,例如-XXX_verticalTextAlignment. 但这不现实,不是吗?

问题2
我知道这种意外覆盖发生在编译时或更新 iOS SDK、OSX SDK 或 XCode 时。

但是在更新 iPhone 的 iOS 版本时是否也会发生这种情况?
例如,是否有可能您的应用在 iOS5 上运行良好但在 iOS6 上由于意外覆盖而无法在 iOS6 上运行。(您可以将 iOS5 和 iOS6 替换为任何版本,例如 iOS5.0 和 iOS5.1)

4

4 回答 4

5
  1. 是的,您可以使用自己的前缀,但这并不常见。

  2. 是的,它可以在操作系统更新之后发生;Objective-C 是一种非常动态的语言,其中消息被发送到方法而不是像其他语言那样被调用。这些事情是在运行时解决的,而不是编译时。

底线是肯定的,您可能会不小心覆盖未来的基类方法,唯一的解决方案是在它发生时在那里并重命名该方法。

于 2012-08-21T07:00:51.830 回答
1

在每个不断增长的、非命名空间的可可生态系统中,为您的类别方法添加前缀是避免这些冲突的最安全方法。

框架创建者、开源开发者和其他个人开发者应该为他们的类方法添加前缀是非常有效和合理的。

很多时候,我编写的方法都以我的公司首字母为前缀,然后继续使用该方法。

- (void)JCMyMethodNamedSimilarToBaseClass;
于 2012-08-21T07:01:25.800 回答
1

问题 1a 类别

使用前缀,或者避免整个混乱并使用函数。

问题 1b 子类方法

如果一个方法做了足够通用的事情,超类也可以实现它,我只需选择一个比 Apple 通常选择的方法名称更“罗嗦”——例如在方法名称中指定一个非标准类型名。当然,这只会降低碰撞的可能性。

如果您需要更高级别的安全性,您可以在执行时对其进行测试(这样您就知道何时引入它们)并希望每个用户都保持最新状态——或者您可以更加依赖 C 和/或 C++(它们确实如此)没有这个问题)。

问题2

但是在更新 iPhone 的 iOS 版本时是否也会发生这种情况?

是的。这不是那么不寻常。当框架更新(例如通过软件更新)时,它们可能包含更新的框架。此代码被加载到 objc 运行时中,您始终可以获取已安装框架的 objc 实现的版本。

在 OS X 上,这也是一个更广泛的问题,您可以很容易地动态加载代码和/或插件。

于 2012-08-21T07:12:35.250 回答
1

一个优雅的解决方案是检查方法是否已经存在,如果不存在则仅添加它:Mountain Lion 中的条件类别

于 2012-08-21T07:25:59.783 回答