I've seen a number of posts related to delegates, and I would like to know the proper way to reference them. Suppose I have an object declared like:
@interface MyViewController : UITableViewController {
id delegate;
}
@property (nonatomic, retain) id delegate;
@end
Through the lifecycle of MyViewController
, it will make calls to methods of its delegate in response to interaction with the user.
When it's time to get rid of an instance of MyViewController
, does the delegate
ivar need to be release
'ed in the implementation's dealloc
method since it is declared with retain
?
Or conversely, should delegate
even be retained? Perhaps it should be @property (nonatomic, assign) id delegate
? According to Apple's docs:
retain ... You typically use this attribute for scalar types such as NSInteger and CGRect, or (in a reference-counted environment) for objects you don’t own such as delegates.
Normally I'd just go with what the docs say, but I've seen a lot of code that calls retain
on a delegate. Is this just "bad code?" I defer to the experts here... What is the proper way to handle this?
The delegate object is retained by the receiver. This is a rare exception to the memory management rules described in Advanced Memory Management Programming Guide. An instance of CAAnimation should not be set as a delegate of itself.
The rule is to not retain it because it's already retained elsewhere and more important you'll avoid retain cycles.
Assign creates a reference from one object to another without increasing the source's retain count. Retain creates a reference from one object to another and increases the retain count of the source object.
You generally want to assign delegates rather than retain them, in order to avoid circular retain counts where object A retains object B and object B retains object A. (You might see this referred to as keeping a "weak reference" to the delegate.) For example, consider the following common pattern:
-(void)someMethod {
self.utilityObject = [[[Bar alloc] init] autorelease];
self.utilityObject.delegate = self;
[self.utilityObject doSomeWork];
}
if the utilityObject
and delegate
properties are both declared using retain
, then self
now retains self.utilityObject
and self.utilityObject
retains self
.
See Why are Objective-C delegates usually given the property assign instead of retain? for more on this.
If you assign the delegate rather than retaining it then you don't need to worry about releasing it in dealloc.
It is usually indicative of bad design, since most delegates retain their objects (creating the potential for retain loops and thus leaks.) But there are some cases where an object should retain its delegate. These are usually cases where no reference is available to the object, so the delegate cannot be the one to retain it--but that itself can sometimes indicate bad design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With