If learned the hard way that you should remove the delegate from an object if the life span of the delegate is shorter than the object. But how do you do this if you don't have a reference to the object anymore?
In my iPhone application I have a view controller vc
which performs an asynchronous activity and is displayed as a modal view. A cancel button dismisses the modal view. If an error occurs, an UIAlertView alert
is displayed. If the user taps on ok, both alert
and the modal view disappear. Therefore vc
is set
as delegate for alert
and implements alertView:didDismissWithButtonIndex:
. Something like this:
// UIViewController vc
...
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Error"
message:@"Something went wrong"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
self.alertView = alert; // needed to unset alertView.delegate in dealloc
[alert show];
[alert release];
...
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[self dismissModalViewControllerAnimated:YES];
}
}
Normally, the alert view blocks all input. Unfortunately, it fails to do so in some edge cases.
If the user touches down on the cancel-button before the alert view appears and touches up after the alert view appears, the view is dismissed, but not the alert. vc
gets deallocated and if the user then taps "ok" on the alert, the application crashes because a message was sent to the released object.
I solved this by assigning alert
to a property of vc
so I can set alert.delegate
to nil in dealloc. I find this solution to be not very elegant, because I don't really need the reference to alert.
Is there a better approach?
Edit: Added the text in italics as clarification