什么是Objective-C类别的作用范围?

13

如果我在分类中覆盖一个方法,它只会影响包含它的文件,还是会影响整个项目?我想重写 "methodSignatureForSelector" 和 "forwardInvocation" 方法,以忽略 NSNull 的未定义选择器错误。所以我想知道这是否只会影响包含该分类的文件。谢谢。


类别是否在单独的文件中? - BoltClock
5
你为什么要做那样邪恶的事情?!?! - bbum
@bbum 我使用了JSON解析器,它会为JSON中的"null"生成NSNull对象。当title是NSNull时,我想忽略调用[title length]时出现的错误。我不确定这是否是正确的方法。 - Fourj
3
不,真的,你不想做那件事。那样做会使你应用程序中的每一个NSNull对象忽略这些消息,并掩盖错误。如果你想让“null”字符串等同于空字符串,则应该在服务器端或解析器上进行更改;不要使用行为奇怪的对象来解决数据模型的脆弱性问题,以免污染对象图形。现在这样做可能看起来很简单,但日后你的理智会受到影响。 - bbum
谢谢。同意你的观点。但是从JSONFramework处理NSNull值仍然很痛苦。找到了一个实用的解决方案:https://dev59.com/2G025IYBdhLWcg3w7qfL#5719428 @bbum - Fourj
1个回答

16

假设您有一个类A和一个定义在其上的类别C。 这两个类都有自己的.h .m文件。

类别会“影响”什么?

就编译而言,只有导入了C.h文件的编译单元(.m文件)。也就是说:在导入该头文件的文件中,您将不会收到未定义选择器的警告(当然是对于在C.h中定义的选择器);但在其他文件中,则会收到此类警告。

至于链接(或执行,在Objective-C中非常接近),则会影响全部可执行文件。

实际上,即使您在B.m中没有导入C.h文件,如果B.m使用了在C.h中定义的选择器,该调用仍将成功(即将有效地使用类别中的实现),但编译B.m时仍会收到警告。如果B.m是在不同的时间编译的(即创建类别之前),这也适用。


谢谢@sergio。换句话说,我无法使用类别覆盖方法并将其应用于项目中仅限于某些.m文件的方式?提前感谢您的澄清。 - Reinhold
最后一段不正确,至少对于Xcode 4而言是如此。如果您不导入类别.h文件,Xcode将发出错误而不是警告。因此,您甚至无法成功构建。导入类别头文件是必须的。 - Philip007

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