EXC_BAD_ACCESS 使用 dispatch_async 时
EXC_BAD_ACCESS when using 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);
});
}
}
y 的常见症状是:
- 发生在 iOS10,永远不会发生在 iOS8
- 在调试期间发生但从未在生产中报告
(这是一个自我回答的问题)
*我们喜欢 dispatch_async
的简单性,不需要 NSOperationQueue
的阻塞/依赖特性,我们很快就会转向 C++,所以希望保持低水平。
经过几天的调试,确保我们的线程对象被强烈保留,并尝试各种弱-强组合并使用 Instruments 进行彻底的分析,我们得出的结论是 这是一个 Apple 错误(还有 ),只出现在最近的 iOS 版本中(对我们来说是 iOS10,但我认为它会在 libBacktraceRecording.dylib
开始时的版本中出现出现)。
以下症状:
- 无法在 iOS8.x
上重现
- 仅在调试模式下发生
- EXC_BAD_ACCESS 在代码的随机部分,没有任何模式
可能表明这一点。
希望这对其他人有用!
我们最近修改了我们的线程机制以支持在大多数地方使用 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);
});
}
}
y 的常见症状是:
- 发生在 iOS10,永远不会发生在 iOS8
- 在调试期间发生但从未在生产中报告
(这是一个自我回答的问题)
*我们喜欢 dispatch_async
的简单性,不需要 NSOperationQueue
的阻塞/依赖特性,我们很快就会转向 C++,所以希望保持低水平。
经过几天的调试,确保我们的线程对象被强烈保留,并尝试各种弱-强组合并使用 Instruments 进行彻底的分析,我们得出的结论是 这是一个 Apple 错误(还有 libBacktraceRecording.dylib
开始时的版本中出现出现)。
以下症状:
- 无法在 iOS8.x 上重现
- 仅在调试模式下发生
- EXC_BAD_ACCESS 在代码的随机部分,没有任何模式
可能表明这一点。
希望这对其他人有用!