objective-c-blocks和ARC – 发布版本的复制或崩溃(由优化级引起
我正在使用
Xcode 4.3.3并开发iOS 5.0.在开发ARC iOS应用程序时,我已经开始使用块作为异步操作的回调机制.该应用程序在模拟器和设备上正常工作.
然后我第一次运行该分析器,并且它几乎马上就开始崩溃 – 特别是在尝试调用第一个回调块时,EXC_BAD_ACCESS. 经过一番调查,很明显,行为的差异是因为在默认情况下,分析器运行在“发布模式” – 特别是优化级别设置为“最快,最小[-Os]”而不是“无[-O0] ”. 例如,以下代码(针对此问题简化)将在尝试执行callbackBlock时崩溃: - (void) setCallbackBlock:(void (^)(NSString *input))block { callbackBlock = block; } - (void) invokeCallbackWithInput:(NSString *)input { if (callbackBlock) { callbackBlock(input); } } 调试到它,调用setCallbackBlock,优化级别设置为“None”,传入的块将是一个NSStackBlock,并且callbackBlock将成为一个NSMallocBlock. 然而,优化级别“最快,最小”,仍然是NSStackBlock. 更改setter代码以使用[block copy]来修复崩溃问题(基于iOS 5 blocks crash only with Release Build). 然而,另一个相关的问题表明,ARC-Why does Objective-C block still work without copying it to the heap?中的ARC – 块变量被复制到堆中不是必需的 所以我的问题:这里发生了什么,为什么? (另外,这两个答案如何正确??) 编辑: @interface MyClass () { void (^callbackBlock)(NSString *input); } @end 解决方法
我实际上认为the other question的答案是错误的,因为它没有回答关于ARC中的块的特定问题.问题是将一个基于堆栈的块从一个函数/方法传递给另一个.答案是一些不同的东西,这是捕获一个块内的__block变量.这是一个不同的问题. 您的问题的答案是Transitioning to ARC Release Notes:的常见问题
所以这样做的方式是,当你传递一个块(在你的情况下是在堆栈上分配的块文字)时,编译器在初始化该调用的参数时不会复制该块.被调用的函数或方法有责任在需要时复制该块本身. 当ARC从函数或方法返回块时,ARC自动复制块.在这种情况下,编译器知道它必须为你做一个复制到堆,所以它. 所以你的设置者应该做一个块拷贝,甚至用ARC. 我希望有帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |