【问题标题】:Why ARC forbids calls to undeclared methods?为什么 ARC 禁止调用未声明的方法?
【发布时间】:2013-12-14 11:22:18
【问题描述】:

当使用手动内存管理时,我们可以编写对未在类中声明的方法的调用。在这种情况下,我们在编译期间得到的只是警告。这是 Wikipedia 对 Objective-C 最独特的特性之一的陈述:

面向对象编程的 Objective-C 模型基于向对象实例传递消息。在 Objective-C 中,不是简单地调用一个方法;而是调用一个方法。一个发送消息。这与 C++ 使用的 Simula 风格的编程模型不同。这两个概念的区别在于方法或消息名称所引用的代码是如何执行的。在 Simula 风格的语言中,方法名称在大多数情况下由编译器绑定到目标类中的一段代码。在 Smalltalk 和 Objective-C 中,消息的目标是在运行时解析的,接收对象自己解释消息

那么为什么在 ARC 中出现编译错误?破坏该语言如此强大功能的原因是什么?我不知道有什么如此重要?有人可以解释一下吗?谢谢

【问题讨论】:

  • 涉及到 NSSelectorFromString 吗?请分享触发错误的代码!
  • 不,您可以使用 NSSelectorFromString 来逃避错误,但我不是在问如何逃避它,而是在问为什么这样做。共享代码的内容然后尝试在 ARC 下调用任何未声明的方法,您就会明白我在说什么

标签: objective-c automatic-ref-counting


【解决方案1】:

在这个讨论中有一些关于它的信息:

在 ARC 下,编译器现在需要准确的所有权 方法返回。这种情况下的默认值是对象不是 由调用者拥有,但在实际声明中,对象可能是 由调用者拥有(“ns_returns_retained”属性),相反,您 可能有一个像 newBar 这样的拥有方法,它返回一个非保留的 对象(“ns_returns_not_retained”属性),在前一种情况下,您 在后者中获得不足释放,您将获得过度释放,即 对 ARC 不利。

为了使 ARC 具有确定性,编译器必须假设很多事情 所以某些以前可以的行为在 ARC 中被定为非法行为 确保行为一致。

这个回复似乎来自一位 Apple 开发者:

我们的推理在 (1) 需要更多 小心类型和所有权,以及 (2) 想要消除 语言上令人尴尬的疣(不允许抱怨 完全未知的方法,比一个更费力的方法 警告)。调用方法确实没有正当理由 这甚至没有在某处宣布。这样做的能力使一些 真正微不足道的错误(例如选择器中的拼写错误)运行时失败 的编译失败。我们一直对此提出警告。修正你的代码。

所以主要论点是编译器需要知道 返回值

【讨论】:

  • 太糟糕了,即使返回类型是 void 并且参数也不是对象,这也会被标记为错误。
【解决方案2】:

ARC 管理保留/释放调用。要正确执行此操作,它需要知道您使用的所有方法的行为方式。

它需要您使用的消息签名。它从头文件中获取它们。因此,它强制您为您使用的所有方法提供标头/声明。

它确实可以在没有标题的情况下工作:您可以使用 NSSelectorFromString 来欺骗它,但这并不安全,并且 arc 希望在默认情况下确定所有内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 2013-05-10
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多