I have narrowed down an ugly bug, but since it seems like something internal to the nib/Interface Builder, I'm at a loss of what to do next.
I've got a UIView created in IB which functions as a custom dialog box. It shows a message and two buttons. (Proceed or Cancel.) Both buttons have a Background image set in Interface Builder.
Something is wrong with the way the background image for the cancel button is being handled. With NSZombieEnabled, I've been running the program. Most often, the method below logs this:
-[ModalDialog showInView:title:message:cancelText:proceedText:]
dialogProceedButton <UIButton: 0x7031f10; frame = (286 192; 90 31) // (etc.)
dialogProceedButtonBackground <UIImage: 0x3b36120>
dialogCancelButton <UIButton: 0x3b39cd0; frame = (104 192; 90 31) // (etc.)
dialogCancelButtonBackground <UIImage: 0x3b3a920>
That's completely normal. However, sometimes it does this (I can get this to repeat somewhat reliably if I "rush" the UI by rapid tapping some interface buttons):
-[ModalDialog showInView:title:message:cancelText:proceedText:]
dialogProceedButton <UIButton: 0x7031f10; frame = (286 192; 90 31) // (etc.)
dialogProceedButtonBackground <UIImage: 0x3b36120>
dialogCancelButton <UIButton: 0x3b39cd0; frame = (104 192; 90 31) // (etc.)
*** -[UIImage retain]: message sent to deallocated instance 0x3b3a920
As you can see, NSZombieEnabled found that the background image for the Cancel button has been deallocated, but is being sent a retain message. (Not by me, though... that image is only used for this one button, and only accessed in Interface Builder. I don't have any IBOutlets or any variables linked to that image.)
So, um, what now?
EDIT:
Sometimes, it's not a retain message that gets caught as a zombie, sometimes it's isKindOfClass:
//(the object address is always dialogCancelButton.currentBackgroundImage)
-[UIImage isKindOfClass:]: message sent to deallocated instance 0x1661f0
//occasionally, these come along, too:
*** NSInvocation: warning: object 0x7e0d0b0 of class '_NSZombie_UIImage' does not implement methodSignatureForSelector: -- trouble ahead
*** NSInvocation: warning: object 0x7e0d0b0 of class '_NSZombie_UIImage' does not implement doesNotRecognizeSelector: -- abort
This is my custom UIViews "showInView" method:
- (void)showInView:superView
title:(NSString*)title
message:(NSString*)message
cancelText:(NSString*)cancelText
proceedText:(NSString*)proceedText {
NSLog(@"%s",__PRETTY_FUNCTION__);
NSLog(@"dialogProceedButton %@", dialogProceedButton);
NSLog(@"dialogProceedButtonBackground %@", dialogProceedButton.currentBackgroundImage);
NSLog(@"dialogCancelButton %@", dialogCancelButton);
NSLog(@"dialogCancelButtonBackground %@", dialogCancelButton.currentBackgroundImage);
CGRect rect;
dialogTitle.text = title;
dialogMessage.text = message;
[dialogProceedButton setTitle:proceedText forState:UIControlStateNormal];
if (cancelText == @"") { // SINGLE BUTTON DIALOG
dialogCancelButton.hidden = YES;
rect = [dialogProceedButton frame];
rect.origin.x = 195; //center the button
[dialogProceedButton setFrame:rect];
} else {
[dialogCancelButton setTitle:cancelText forState:UIControlStateNormal];
dialogCancelButton.hidden = NO;
rect = [dialogProceedButton frame];
rect.origin.x = 286; //button on right of dialog box
[dialogProceedButton setFrame:rect];
}
[UIView beginAnimations:@"modalAppears" context:nil];
[UIView setAnimationDuration:0.5];
[superView addSubview:self];
self.alpha = 1.0;
[UIView commitAnimations];
}
Thanks!