【问题标题】:Cause of iOS ARC over-release crash on XCode 6.4 optimised build?XCode 6.4 优化版本上 iOS ARC 过度发布崩溃的原因?
【发布时间】:2015-07-18 23:16:39
【问题描述】:

以下方法由于 inputLower 的早期 ARC 版本而崩溃,即使范围内仍有强 ptr。这是使用 XCode 6.4 为 ARM64 构建的,只有在使用 -Os 优化时才会崩溃。这是一个 ARC 错误,还是我犯了某种 ARC 逻辑错误?

void crasher(NSString * input) {
    NSString * inputLower = [input lowercaseString]; // should be strong ptr
    NSString * inputLower2 = inputLower; // should be a 2nd, independent strong ptr        
    int i = 1;
    while (i < 10) {
        inputLower2 = [NSString stringWithFormat:@"%@%d", inputLower, i++];
        // ERROR: inputLower is released here, so the next iteration will crash
        NSLog(@"%@", inputLower2);
    }
}

只需添加一个副本就可以避免崩溃,但我已经详细阅读了 ARC 规则,我认为这不是必需的:

NSString * inputLower2 = [inputLower copy];

如果这不是我的错,我会向 Apple 提交错误。

【问题讨论】:

  • "这是一个 ARC 错误,还是我犯了某种 ARC 逻辑错误?"两者都不。它与ARC无关。它与优化有关(正如您正确建议的那样),也许与绑定到 Xcode 的性质有关。尝试在设备上独立运行此应用程序 - 也就是说,从 Xcode 内启动,因此不与 Xcode 绑定。现在它崩溃了吗?
  • 是的,它在不受限制且未调试时崩溃,但只有在优化构建运行时才会崩溃。如果在没有调试的情况下运行未优化的构建,它不会崩溃。事实上,这是一份来自现场的崩溃报告,它提醒了我这个问题。在我看来,优化确实是使指针别名假设与 ARC 规则冲突。
  • 等一下,我无法重现崩溃...给我一秒钟尝试让它崩溃。
  • 好吧,崩溃了!让我看看我能不能玩一下。
  • 这是while循环内的NSLog;一些东西正在被优化掉。如果您将 NSLog 移动到 while 循环之后,您会看到循环正常工作。

标签: ios objective-c xcode automatic-ref-counting arm64


【解决方案1】:

我以前见过这种事情。与其说是 ARC 问题,不如说是优化问题,尤其是 NSLog 引发了它。在这种情况下,是 while 循环中的 NSLog 导致了问题;一些东西正在被优化掉。如果您将 NSLog 移动到 while 循环之后,您会看到该循环有效。

此外,我无法在 Xcode 7 中重现崩溃(这就是为什么我花了这么长时间才重现它;我不得不专门切换到 Xcode 6.4)。这表明苹果公司的人确实知道这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 2023-03-15
    • 1970-01-01
    • 2018-09-24
    相关资源
    最近更新 更多