Reputation: 3286
We have recently revised our threading mechanism in favour of using dispatch_async
's in most places (after doing a lot of reading about NSOperation vs dispatch_async)*. Then our code started crashing with EXC_BAD_ACCESS in various parts of the code, always on the dispatch_async(queue,...)
part, with no clear pattern. Usually happening after 20 minutes - 2 hours.
Our dispatch_async
blocks were used to notify listeners, looked as follows:
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 common symptoms were:
(This is a self-answered question)
*We liked the simplicity of dispatch_async
, didn't need the blocking / dependency features of NSOperationQueue
's and we will be moving to C++ soon so wanted to stay low level.
Upvotes: 1
Views: 1556
Reputation: 3286
After days of debugging, ensuring our thread objects were strongly retained, and trying various weak-strong combinations and thorough profiling using Instruments, we have come to the conclusion that this is an Apple bug (as also reported here) that only appears on recent iOS versions (iOS10 for us, but I reckon it will be present from the version when libBacktraceRecording.dylib
started appearing).
Symptoms of:
might indicate this.
Hope this is useful for others!
Upvotes: 5