views:

131

answers:

2

Hi all, I implemented the delegate-callback pattern between two classes without retaining the delegate. But in some cases, the delegate is dealloced.

(My case is that I have a ViewController is the delegate object, and when the user press back button to pop that ViewController out of the NavigationController stack)

Then the callback method get BAD_EXE:

if (self.delegate != nil && [self.delegate respondsToSelector:selector]) {
    [self.delegate performSelector:selector withObject:self withObject:returnObject];
} 

I know the delegate-callback pattern is implemented in a lot of application. What is your solution for this?

+1  A: 

Generally, a delegate should always deassociate it from its delegating object in its dealloc method. So your view controller should check in its dealloc whether it is set as the delegate of the delegating class, and if so, set the delegate property to nil.

In most cases, I would imagine this would not be a problem because very often the delegate is the sole owner of the delegating object. So when the delegate gets deallocated, the delegating object would get deallocated too. After all, this is the reason that delegating objects usually only hold weak references to their delegates.

Ole Begemann
I try to follow the way NSURLConnection implementing delegate - callback. Using this I don't have to retain the delegating object.ClassA:Initalize NetworkClass, call it perform task NetworkClass *networkObject = [[NetworkClass alloc] init]; [networkObject getSomethingWithDelegate:self];When callbacking, NetworkClass passes it self to release in ClassA- (void)networkClass:(NetworkClass *)networkObject didGetSomething:(NSObject *)returnObject { // do with returnObject [networkObject release]; networkObject = nil;}But I may have to change this to do like you said.
Thanh-Cong Vo
I am trying to release the delegating object when release the delegate object. However, in some library, for example like MGTwitterEngine, NSURLConnection, the delegating object retain itself and then I can not release the delegating object. Do you have any idea?
Thanh-Cong Vo
I said that you should set the delegate property to nil (in certain circumstances), not that you should release anything. You must NEVER release an object that you don't own. I honestly do not understand your question.
Ole Begemann
A: 

I have no objective-c knowledge, but I would think that you need to test for self.delegate != nil separately e.g

if (self.delegate != nil)
{
 if ( [self.delegate respondsToSelector:selector]) 
 {
    [self.delegate performSelector:selector withObject:self withObject:returnObject];
 }
}

Oh and it's best to reassign the delegate if it is nil.

ChrisBD
No, that won't help. The `delegate` property will still point to a memory address but the object that was at that address got deallocated. There wouldn't be a problem if the delegate was `nil`.
Ole Begemann
Okay. Just wondering as I've come across the problem before where the testing for a "nil" or "null" value as well as checking that it can have another value causes problems. From what you say I take it that this isn't a problem with objective-c.I understood the OP said that the delegate had been deallocated, but now I see that this is not always the case.
ChrisBD