醜いバグを絞り込みましたが、nib/Interface Builder の内部にあるように見えるので、次に何をすべきか途方に暮れています。
カスタム ダイアログ ボックスとして機能する IB で作成された UIView があります。メッセージと 2 つのボタンが表示されます。(続行またはキャンセル) どちらのボタンにも、Interface Builder で設定された背景画像があります。
キャンセルボタンの背景画像の扱いに問題があります。NSZombieEnabled を使用して、プログラムを実行しています。ほとんどの場合、以下のメソッドはこれをログに記録します。
-[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>
それは完全に正常です。ただし、これを行う場合もあります (いくつかのインターフェイス ボタンをすばやくタップして UI を「急ぐ」と、これをある程度確実に繰り返すことができます)。
-[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
ご覧のとおり、NSZombieEnabled は [キャンセル] ボタンの背景画像の割り当てが解除されていることを検出しましたが、保持メッセージが送信されています。(ただし、私ではありません...その画像はこの1つのボタンにのみ使用され、Interface Builderでのみアクセスされます。その画像にリンクされたIBOutletsまたは変数はありません。)
それで、ええと、今何ですか?
編集:
ゾンビとして捕捉されるのは保持メッセージではない場合もあれば、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
これは私のカスタム UIViews "showInView" メソッドです:
- (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];
}
ありがとう!