【问题标题】:EXC_BAD_ACCESS when copying or retaining Block复制或保留块时的 EXC_BAD_ACCESS
【发布时间】:2025-12-06 05:50:02
【问题描述】:

据我了解,块就像一个对象,因为您可以向它发送复制或发布消息,例如:

[myBlock copy];

但是,每当我这样做或释放一个块时,我都会得到 EXC_BAD_ACCESS。

如果我使用块函数,一切都会按预期工作,例如:

Block_copy(myBlock);

我认为释放和复制块的方式是相同的?

这不是什么大问题,但是如果我有一个属性(副本)是一个Block,我必须自己编写setter方法,这有点烦人。

例如:带属性:

//Header
@property (nonatomic, copy) void (^cancelledBlock)(void);

//Implementation
@sythesize cancelledBlock;

设置cancelledBlock时导致EXC_BAD_ACCESS

但如果我这样做:

//Header
@property (nonatomic, copy) void (^cancelledBlock)(void);

//Implementation
@sythesize cancelledBlock; //saves me doing the getter as well

- (void)setCancelledBlock:(void (^)(void))aCancelledBlock {
    if (cancelledBlock == aCancelledBlock) {
        return;
    }
    void (^oldValue)(void) = cancelledBlock;
    cancelledBlock = Block_copy(aCancelledBlock);
    Block_release(oldValue);

}

没有 EXC_BAD_ACCESS,一切正常运行。

【问题讨论】:

  • 您应该只发布您之前保留或复制的内容。
  • 我知道,正如我在我的问题中所说,尝试执行 [myBlock copy] 会给出 EXC_BAD_ACCESS,但 Block_copy(myBlock) 不会
  • 你能给我们看一个完整的例子吗?
  • 没有真正的例子,我使用块的地方都是一样的。
  • 复制的块属性工作得很好。如果您的情况不是这样,您应该创建并上传一个我们可以尝试的简单演示项目。

标签: iphone objective-c exc-bad-access objective-c-blocks


【解决方案1】:

经过漫长而无聊的下午和晚上后,我终于找到了这个answer here,虽然它看起来似乎无关,但我访问的一系列网站却创造了这种关系。

基本上,我必须从链接器标志中删除-weak_library /usr/lib/libSystem.B.dylib,并将其替换为-weak-lSystem

【讨论】:

  • 谢谢你,乔纳森! 4个多小时后你解决了我的问题!
  • 哇。我确实花了数周时间试图找出导致我的应用程序在模拟器中启动时崩溃的原因。这个答案做到了。非常感谢!
  • 我知道这个问题有多烦人,我只是希望我知道为什么这个解决方案有效。
  • 我希望 SO 中有一个捐赠系统,所以我可以给你 1000 分这个答案。我不确定自己是否能在几个漫长而无聊的下午找到原因。