【问题标题】:Message passing - compiler won't check whether method is existing?消息传递 - 编译器不会检查方法是否存在?
【发布时间】:2013-08-10 02:41:20
【问题描述】:

在 Objective-C 的 Wiki 页面中,有一个名为 Messages 的部分。它说编译时,Objective-C 不关心对象是否具有给定方法,因为任何人都可以向另一个对象发送消息。这是动态绑定。

在 C++ 中,obj->方法(参数);如果没有方法,那就错了。 在 Objective-C 中,[obj 方法:参数];如果没有方法,也可以。

但是在我的日常编码中,使用 XCode,如果编译器找不到对象的公共方法,它甚至在构建之前总是提示错误。像这样,

“ClassName”没有可见的@interface 声明选择器“methodName”

我对这个“矛盾”有点困惑。如果问题很愚蠢,请原谅我。提前致谢。

【问题讨论】:

  • 即使在 ARC 之前,如果您尝试调用未定义的方法,编译器也会发出警告。除其他事项外,这还提供了极大的便利——您知道自己在编码时输入错误,而必须深入测试会话才能发现您输入的是 x 而不是 s。

标签: ios objective-c


【解决方案1】:

我认为编译器只是在保护您免受自己的伤害。在您注意到的情况下,编译器知道您正在调用的方法不存在,因此将其报告为错误。

但是,如果你告诉编译器你不在乎或者没有给它足够的信息,那么它是完全有效的。

例子:

NSString* var = @"Hello";
[(id)var thisDoesNotExist];

id var2 = @"Hello";
[var2 neitherDoesThis:var];

这些(应该)都可以编译。

【讨论】:

  • 我不认为这是 the 原因 - 至少在 OP 的具体情况下不是。 (否则你在这里描述的是真的,它只是不适合这个问题。)
【解决方案2】:

您可能会使用 ARC。为了编译启用 ARC 的代码,编译器需要知道方法期望作为参数并作为返回值返回的对象类型,以便能够发出对内存管理方法的必要调用。因此,当您编译 ARC 代码时,编译器检查方法签名是否存在。

但是,如果您使用手动引用计数 (MRC),则编译器不需要此信息用于此目的(其中一些信息仍然需要生成符合ABI),如果找不到某个消息/方法/选择器,它不会发出错误。但是,它确实会发出警告以确保安全。

【讨论】:

  • 谢谢!我只是尝试在没有 ARC 的情况下创建一个新项目并输入一些测试代码。是的,它会发出警告,但构建可以通过。 [混淆集IsSolved:YES];
  • 编译器还需要知道没有 ARC 的参数类型。警告意味着编译器必须猜测类型是什么。如果它猜错了,它会错误地编译你的代码。修复警告。
  • “编译器不需要此信息”为假。编译器确实需要它。如果可以的话,我们会在任何地方将此警告升级为错误。
  • @H2CO3 编译器确实 需要MRC 中的信息,当所述信息不存在时,它只是宽松地处理。它编译并不意味着生成的代码有效。这不仅与保留/释放行为有关,还与调用站点本身有关。例如,如果没有精确、明确的类型信息,编译器将不知道要使用objc_msgSend() 的哪个变体。该警告始终应该是一个硬错误,但有太多代码依赖于模棱两可的行为。
  • @bbum 我知道。我知道这一切,我写了几个答案,问“为什么在 C 中需要声明”。 GregParker 用来扭曲我的话只是我使用的语言/措辞中的一个错误。我希望您注意到答案中的“生成符合 ABI 的代码仍然需要其中一些”部分!?
猜你喜欢
  • 2013-11-13
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 2014-06-18
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
相关资源
最近更新 更多