dispatch_source_set_cancel_handler and assigning nil to @property ivar
-
07-12-2019 - |
Question
When you have a cancel_handler for a timer, can you directly reference and reset any ivars declared as a property with 'assign' attribute or do you have to first assign it as a __block?
@interface SomeClass: NSObject { }
@property (nonatomic, assign) dispatch_source_t timer;
@end
// Class implementation
@implementation SomeClass
@synthesize timer = _timer;
- (void)startTimer
{
dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0, globalQ);
dispatch_time_t startWhen = dispatch_walltime(DISPATCH_TIME_NOW, NSEC_PER_SEC * 1);
dispatch_source_set_timer(_timer, startWhen, 1 * NSEC_PER_SEC, 5000ull);
dispatch_source_set_event_handler(_timer, ^{
// timer's event handler
});
// VERSION 1:
// Is it okay to reference and assign self.timer to nil
// or does it have to be declared as __block as in VERSION 2?
dispatch_source_set_cancel_handler(_timer, ^{
dispatch_release(_timer);
self.timer = nil;
});
// VERSION 2:
__block myTimer = self.timer;
dispatch_source_set_cancel_handler(_timer, ^{
dispatch_release(myTimer);
myTimer = nil;
});
dispatch_resume(_timer);
}
Solution
You can reference ivars just fine. However, these references carry an implicit reference to self
, so you need to be wary of retain cycles. For example, if you reference an ivar directly, don't expect to shut down the timer in -dealloc
because that will never be called.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow