In a non-ARC app, I have an NSOperation subclass which is enqueued by a delegate and looks like:
// note that the delegate and element properties are retained
-(id)initWithDelegate:(id<SomeDelegate>)inDelegate element:(SomeElement *)inElement
{
if (self = [super init])
{
[self setDelegate:inDelegate];
[self setElement:inElement];
}
}
-(void)dealloc
{
[_delegate release];
[_element release];
[super dealloc];
}
-(void)main
{
// do stuff
dispatch_async(dispatch_get_main_queue(), ^{
[[self delegate] doSomething:[self element]];
});
}
Since [[self delegate] doSomething:[self element]] will be called after my NSOperation object has likely been deallocated, do I need to make sure to retain "element" in the delegate before adding this operation to the queue? The element object is retained elsewhere in the app but it could potentially be released there. I need to make sure that when my delegate receives it back from the NSOperation, that it is still a valid object.
Just wondering if the act of invoking it in dispatch_async will retain the arguments passed to it. I could of course use an NSInvocation and performSelectorOnMainThread which would retain it.
The queue will retain the Block when it's enqueued, and the Block will retain objects that it captures, such as self
. Since self
here has a strong reference to its element
, the element
will be valid at least until after the Block runs.
Note that it's unusual for an object to have a strong reference to its delegate: make sure you don't have an unbroken retain cycle there.