gpt4 book ai didi

objective-c - block 和 ARC - 发布版本复制或崩溃(由优化级别引起)

转载 作者:技术小花猫 更新时间:2023-10-29 11:15:16 31 4
gpt4 key购买 nike

我正在使用 Xcode 4.3.3 并针对 iOS 5.0+ 进行开发。在开发 ARC iOS 应用程序时,我开始使用 block 作为异步操作的回调机制。该应用程序在模拟器和设备上运行良好。

然后我第一次运行探查器,它几乎立即开始崩溃 - 特别是在尝试调用第一个回调 block 时出现 EXC_BAD_ACCESS。

经过一些调查,很明显行为上的差异是因为分析器默认以“ Release模式”运行 - 特别是优化级别设置为“最快,最小 [-Os]”而不是“无 [ -O0]".

例如,以下代码(针对此问题进行了简化)在尝试执行回调 block 时会崩溃:

- (void) setCallbackBlock:(void (^)(NSString *input))block
{
callbackBlock = block;
}

- (void) invokeCallbackWithInput:(NSString *)input
{
if (callbackBlock) {
callbackBlock(input);
}
}

对其进行调试,调用优化级别设置为“无”的 setCallbackBlock,传入的 block 将是一个 NSStackBlock,而 callbackBlock 将成为一个 NSMallocBlock

但是,在优化级别为“最快、最小”的情况下,它仍然是一个 NSStackBlock

将 setter 代码更改为使用 [block copy] 修复了崩溃问题(基于 iOS 5 blocks crash only with Release Build )。

但是,另一个相关问题表明这对于 ARC 来说不是必需的 - block 变量被复制到 ARC 中的堆中 - Why does Objective-C block still work without copying it to the heap?

所以我的问题是:这是怎么回事,为什么? (另外,这两个答案怎么可能都是正确的...?)

编辑:为了阐明 callbackBlock 是如何声明的——就在我的@implementation 上面,这些方法是这样的:

@interface MyClass ()
{
void (^callbackBlock)(NSString *input);
}

@end

最佳答案

So my question: What's going on here, and why? (Also, how can both of those answers be correct...?)

我实际上认为 the other question 的答案是错误的,因为它没有回答有关 ARC 中 block 的特定问题。问题是关于将基于堆栈的 block 从一个函数/方法传递到另一个函数/方法。答案是关于一些不同的东西,它是在 block 中捕获 __block 变量。那是一个不同的问题。

您问题的答案在Transitioning to ARC Release Notes: 的常见问题解答中。

Blocks “just work” when you pass blocks up the stack in ARC mode, such as in a return. You don’t have to call Block Copy any more. You still need to use [^{} copy] when passing “down” the stack into arrayWithObjects: and other methods that do a retain.

所以它的工作方式是,当您传递一个 block (在您的情况下是分配在堆栈上的 block 文字)时,编译器在为该调用初始化参数时不会复制该 block .被调用的函数或方法有责任在需要时复制该 block 本身。

当您从函数或方法返回 block 时,ARC 会自动复制 block 。在这种情况下,编译器知道它必须为您复制到堆中,它确实这样做了。

因此即使使用 ARC,您的 setter 也应该进行 block 复制。

希望对您有所帮助。

关于objective-c - block 和 ARC - 发布版本复制或崩溃(由优化级别引起),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12061756/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com