XCode 4.5 警告父/子类的类别之间的方法名称冲突

Posted

技术标签:

【中文标题】XCode 4.5 警告父/子类的类别之间的方法名称冲突【英文标题】:XCode 4.5 warns about method name conflicts between Categories for parent/child classes 【发布时间】:2012-11-14 22:24:12 【问题描述】:

我正在开发一个最初使用 XCode 4.0 构建的项目,然后迁移到使用 XCode 4.2。现在我已经测试了迁移到 XCode 4.5,我收到了大量如下警告...

instance method 'values' in category from <pathToTheFile>/HistoryObject+extras.o conflicts with same method from another category

这些警告从未出现在以前版本的 XCode 中,代码也没有改变。

项目的部署目标设置为 ios 4.3。

所以,我们从以前的开发人员那里得到了一堆 DAO 类型的类,我相信它们是从 CoreData 自动生成的,然后这些类中的每一个都有一个 Category 扩展它以实现某些方法。我举个例子……

我们有一个名为 LisaObject 的基类,它继承自 NSManagedObject,它有一个名为 LisaObject+extras 的类别。在 LisaObject+extras 中,有一个名为“values”的方法,它返回一个 NSMutableDictionary。

然后我们有一个名为 HistoryObject 的类,它继承自 LisaObject。 HistoryObject 还有一个名为 HistroyObject+extras 的类别。此类别还有一个名为“值”的方法。在 HistoryObject+extras values 方法中,它调用[super values],然后检查一些条件并在字典中设置一些在基类方法中没有设置的附加值。

然后我们有一个名为 LessonStatusObject 的类,它继承自 HistoryObject,它也有一个名为 LessonStatusObject+extras 的类别,它有一个名为 values 的方法。这个 values 方法还调用 [super values] 然后对返回的字典做一些额外的工作。

对于这些“值”方法中的每一个,我们都会在编译时收到一条警告,如上图所示,其中指出 Category 有一个名称冲突的方法。

我对此有几个问题。

首先,这种实现是否会导致任何合法问题,或者这些警告通常是良性的?我试图思考这个实现如何在运行时导致歧义,但我不明白这是怎么发生的。

其次,我应该做些什么来修复这些警告(我的意思不是让它们停止出现;我的意思是修复原因)?我们还有其他方法可以解决这个问题吗?

另外,为什么 XCode 4.2 不会对此发出警告,而 XCode 4.5 会发出警告?

我对类别有什么误解吗?我的意思是,如果“values”方法实际上是每个类实现的一部分,那么以我们的方式覆盖它们不会有问题,但编译器似乎只是因为这些是类别而抱怨。这有什么不安全的地方吗?

非常感谢任何建议。

编辑:只是为了提供更多信息...当我们使用 XCode 4.2 时,该项目将编译器设置为 Apple LLVM Compiler 3.0。现在,当我在 XCode 4.5 中打开项目时,它的编译器设置为 Apple LLVM Compiler 4.1。

【问题讨论】:

【参考方案1】:

我遇到了同样烦人的问题,结果发现我不小心在我的一个 VC 代码中包含了该类别的 .m 文件而不是 .h 文件。将其更正为 .h 文件删除了链接器警告。

【讨论】:

感谢您的建议,我会检查以确保这不是问题。 这也发生在我身上。我建议看到这个的其他人在他们的整个项目中搜索字符串'.m"'。【参考方案2】:

不要忽略警告。

Apple 的“使用 Objective-C 编程”指南在“Customizing Existing Classes”部分中说:

如果类别中声明的方法名称与方法名称相同 在原始类中,或者在同一类的另一个类中的方法 类(甚至是超类),行为是不确定的 方法实现在运行时使用。

如果它对你有用,那是运气。

【讨论】:

我可以理解在同一个类中具有相同方法名称的两个类别会存在歧义。我看不出当超类和子类具有两个不同的类别且方法名称相同时会如何存在歧义。这与覆盖普通实例方法有什么不同?您能否解释一下可能导致歧义的类别是否存在差异? 我实际上并不具体知道为什么该行为未定义,这就是我遵循 Apple 文档的原因。我当然有兴趣知道为什么,我自己。 感谢您的回复。尽管如此,我真的很想知道是否有必要进行重大更改以修复所有这些警告,如果真的永远不可能在运行时引起合法的歧义。很明显,为什么同一类中具有相同方法名称的两个类别会导致歧义,但为什么两个不同类上的两个类别(父/子)可能会导致歧义却没有任何意义。这没有任何意义;每个类都有自己的一组方法,如果名称相同,则子类应覆盖父类的方法。使用类别如何改变这一点? 这只是我的猜测,但是mb类别不是在编译时而是在运行时添加方法,因此,它是什么类(子类或超类)并不重要,它会尝试将此方法添加到没有任何特定顺序的两个类(例如,第一个超类类别而不是子类) @Ossir 很好的评论,你可能是对的。我认为我们需要一位真正的 Apple 工程师来明确回答这个问题,但知道其他功能有多么独特,你的疯狂猜测可能是正确的。【参考方案3】:

我也有这个问题,但又是由不同的东西引起的。对我来说,这个类别已经被添加到 Xcode 项目中两次了!直到我去重命名其中一个方法并在重构预览中看到它两次列出了类别文件时,我才发现是这种情况。

【讨论】:

以上是关于XCode 4.5 警告父/子类的类别之间的方法名称冲突的主要内容,如果未能解决你的问题,请参考以下文章

当我在 xcode 5 中打开我的 xcode 4.5 项目时收到警告

这些 Dsymutil 警告在 XCode 4.5 中意味着啥?

Xcode 8 Objective-C 类别警告

java重写和重载

java多态中父类和子类一定要有一样的方法名吗

java多态