Hi,
I'm using a dispatch source as a timer, I noticed that when the object that contains it is deallocated I get a crash:
libdispatch.dylib`_dispatch_xref_dispose:
0x100134ac8 <+0>: ldr w8, [x0, #48]
0x100134acc <+4>: cmp w8, #2
This happens only if the dispatch source had been suspended, according to the documentation (https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/GCDWorkQueues/GCDWorkQueues.html)
You can suspend and resume the delivery of dispatch source events temporarily using the
dispatch_suspend
and dispatch_resume
methods. These methods increment and decrement the suspend count for your dispatch object. As a result, you must balance each call to dispatch_suspend
with a matching call to dispatch_resume
before event delivery resumesSo I'm wondering if it's not possible to dispatch_source_cancel a suspended dispatch source. Actually the crash is when dealloc ends, the dispatch_source_cancel seems to always work.
Here's my code:
@interface DispatchTimer(){
dispatch_source_t dispatchSource;
NSString *uniqueId;
}
@end
@implementation DispatchTimer
- (void)dealloc {
NSLog(@"DEALLOCATED DispatchTimer");
if(dispatch_source_testcancel(dispatchSource) == 0){
dispatch_source_cancel(dispatchSource);
}
}
- (instancetype)init{
self = [super init];
if (self) {
uniqueId = [[NSUUID UUID] UUIDString];
dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 0);
uint64_t intervalTime = (int64_t)(1 * NSEC_PER_SEC);
dispatch_source_set_timer(dispatchSource, startTime, intervalTime, 0);
__weak DispatchTimer *weakSelf = self;
dispatch_source_set_event_handler(dispatchSource, ^{
[weakSelf update];
});
dispatch_resume(dispatchSource);
}
return self;
}
- (void)stop{
dispatch_suspend(dispatchSource);
}
- (void)update{
NSLog(@"Update %@", uniqueId);
}
If method 'stop' is called when the DispatchTimer is deallocated I get the crash, if stop is not called everything seems to be fine.
In the docs they mention dispatch_release but I get an error when using it in ARC.
Thanks for any help.