使用dispatch_async时EXC_BAD_ACCESS

Ege*_*nar 1 exc-bad-access dispatch grand-central-dispatch ios dispatch-async

我们最近修改了我们的线程机制,支持dispatch_async在大多数地方使用'(在做了很多关于NSOperation和dispatch_async的阅读之后)*.然后我们的代码开始在代码的各个部分与EXC_BAD_ACCESS崩溃,总是在dispatch_async(queue,...)部分,没有明确的模式.通常在20分钟后发生--2小时.

我们的dispatch_async块用于通知听众,如下所示:

NSMutableSet *_listeners; // Initialised elsewhere and filled with interested listeners
void(^block)(id listener); // Block to execute

@synchronized(_listeners) {
  for (id listener in _listeners) {
    dispatch_async_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // We used different queues for different listeners, but showing only one type of queue here for brevity
    dispatch_async(queue, ^{ // CRASHING LINE
      block(listener);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

常见的症状是:

  • 发生在iOS10上,从未在iOS8上发生过
  • 在调试期间发生但从未报告过生产

(这是一个自我回答的问题)

*我们喜欢简单dispatch_async,不需要阻止/依赖功能,NSOperationQueue我们很快就会转向C++,所以想保持低水平.

Ege*_*nar 5

经过几天的调试,确保我们的线程对象得到了强有力的保留,并尝试使用Instruments进行各种弱强组合和彻底的分析,我们得出的结论是,这是一个仅在最近的iOS上出现的Apple bug(也在此处报道)版本(对我们来说是iOS10,但我认为它会在libBacktraceRecording.dylib开始出现时出现在版本中).

症状:

  • 在iOS8.x上无法重现
  • 仅在调试模式下才会发生
  • EXC_BAD_ACCESS代码的随机部分,没有任何模式

可能表明这一点.

希望这对其他人有用!