【问题标题】:How do you handle 'require( ..., bail)' statements with ARC?您如何使用 ARC 处理“require(..., bail)”语句?
【发布时间】:2012-07-09 03:43:48
【问题描述】:

我正在查看Square Cam in Apple's sample code 的一些示例代码。我想在使用 ARC 的现代项目中复制它的一些功能。但是,有大量的 require 语句,例如:

BOOL success = (destination != NULL);
require(success, bail);

这会产生编译器错误:

转到受保护的范围。

我的问题是——在使用 ARC 的项目中处理此类语句的适当方法是什么?

【问题讨论】:

  • 还有一点需要注意——我想过简单地将控制器标记为不使用 ARC,但这并不理想,因为在文件中工作会很困难。标记第三方库不使用 ARC 很好,但如果它是项目实施的一部分,它将创建一个糟糕的工作流程,因为 XCode 在您打开文件时仍然会生成编译器错误/警告。在给定控制器的源代码中工作时,不可能看到实际的警告或错误。
  • 我没有收到这样的错误。你的“保释”线在哪里?还是您按原样使用示例代码?
  • 人们对我的问题投反对票是否有原因?
  • @JimJeffers 我在使用相同的源代码时遇到了同样的问题(再次感谢 Apple),下面接受的答案似乎不适用。您能详细说明您是如何修复这些错误的吗?

标签: objective-c ios automatic-ref-counting llvm


【解决方案1】:

我遇到了同样的问题(使用相同的示例代码)。代码如下所示:

BOOL success = (destination != NULL);
require(success, bail);

//Initialise some variables

bail:
//Deal with errors

我在带有声明的块周围添加了大括号,以明确其范围:

BOOL success = (destination != NULL);
require(success, bail);
{
    // *** Initialise some variables ***
}
bail:
{
    //Deal with errors
}

它为我解决了这个问题。通过查看这个,我还了解到您有时可以扩展构建错误以获取更多详细信息。

【讨论】:

  • 不错的答案+1。只需添加大括号来定义范围是一个很好的解决方案。大多数答案说不要在 goto 下面声明,但是可以使用适当的大括号。
【解决方案2】:

显然bail 在一个具有一个或多个__block 变量的范围内;这是不允许的。有关更多信息,请参阅http://clang.llvm.org/compatibility.html#blocks-in-protected-scope。提出的解决方案是通过将__block 变量放在大括号分隔的块中来限制它们的范围。这可能并不总是有效; YMMV。

【讨论】:

    【解决方案3】:

    我正在为@Lewis42 答案添加一些描述。

    如果你不把变量放在它自己的范围内,你会绕过 goto 之后所有变量的初始化,当 ARC 试图清理它时,它最终会尝试释放一些随机的内存。

    如果您不想将变量放在它们自己的范围内,请确保任何变量都不应该在 goto 关键字下面声明。

    Jumps to within __block variable scope

    __block 需要特殊的运行时初始化。跳转到 __block 变量的范围会绕过这个初始化,留下 变量的元数据处于无效状态。

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 2022-07-15
      • 2021-08-18
      • 2020-04-12
      • 2018-06-24
      • 2018-10-09
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多