views:

514

answers:

2

This code is pretty simple, is it correct? I don't know if I should be retaining the delegate passed in via the init method.

@interface SomeClass : NSObject {
    SomeClassDelegate *someClassDelegate;
}
-(id)initWithDelegate:(SomeClassDelegate *)delegate;
@end

@implementation SomeClass
-(id)initWithDelegate:(SomeClassDelegate *)delegate
{
    [delegate retain]; // should I be doing this?
    someClassDelegate = delegate;
}
-(void)dealloc
{
    [delegate release]; // obviously only do  this if I DO need to retain it
    [super dealloc];
}
@end

My initial thought is no, however this bit of code seems to hint otherwise. I know I can't rely on retain counts, but I'd like to know the proper way to deal with delegates.

// self's retain count is 1
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
// the retain count is now 2, did the init of URLConnection retain self?
+7  A: 

No, in general, you are not supposed to retain the delegate. Since the delegate already has a reference to your object, if you retained the delegate, you would create a circular reference, essentially. Also, for that same reason, you can assume that your object will be destroyed before the delegate is destroyed.

Check out these articles for more information about using/implementing delegates.

EDIT: There are a few exceptions, which have been pointed out by others.

htw
Thanks for the articles, you confirmed my belief on delegates. Mike also explained to me why I see what I see with NSURLConnection in the comments of my question.
Jab
Depending on the situation, your object may not be destroyed first, but it will at least have the delegate unset. (example: UIAccelerometer)
rpetrich
+1  A: 

As htw says, you should not generally retain the delegate. In a multi-threaded environment, you often have to retain everything you need, even if for just a method call's duration, to make sure it doesn't get invalidated behind your back, however. If, for example (not actually the case), the -[NSURLConnection initWithRequest:delegate] created a new thread that thread may have retained (then likely will autorelease) its parameters. In reality, NSURLConnection is a special case in that it retains its delegate for the duration of the connection.

Barry Wark