UIButton, созданный Interface Builder, дает сбой

Я сузил некрасивую ошибку, но поскольку она кажется чем-то внутренним для пера / Interface Builder, я не понимаю, что делать дальше.

У меня есть UIView, созданный в IB, который работает как настраиваемое диалоговое окно. Он показывает сообщение и две кнопки. (Продолжить или Отменить.) Обе кнопки имеют фоновое изображение, установленное в Интерфейсном Разработчике.

Что-то не так с тем, как обрабатывается фоновое изображение для кнопки отмены. С 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>

Это совершенно нормально. Однако иногда он делает это (я могу заставить это повториться с некоторой достоверностью, если я «ускоряю» пользовательский интерфейс, быстро нажимая некоторые кнопки интерфейса):

-[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 обнаружил, что фоновое изображение для кнопки «Отмена» было освобождено, но ему отправляется сообщение о сохранении. (Но не мной ... это изображение только используется для этой кнопки и только доступно в 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

Это мой собственный метод showInView для UIViews:

- (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];
}

Спасибо!


person Rob    schedule 15.10.2009    source источник


Ответы (2)


Хорошо, это черт возьми. Я решил попробовать поменять местами изображения для кнопок «Продолжить» и «Отмена». В результате теперь изображение кнопки Продолжить вызывало сбой (так же периодически). Я полностью удалил изображение из своего проекта и из Interface Builder. Затем я добавил новую копию с новым именем и подключил ее.

С предыдущей настройкой мне удавалось воспроизвести сбой примерно в 40% случаев. Я примерно 20 раз пытался воспроизвести сбой после этих изменений, и сейчас я не могу воспроизвести его вообще.

Если изображение или перо были повреждены, почему, почему, почему это вызывает случайный / прерывистый симптом?

Что за. Надеюсь, что все хорошо и по-настоящему исправлено.


Обновлять:

И ... так что это еще не все. Оказывается, я обнаружил, что случайно использовал то же изображение в качестве заполнителя в моем (неполном) представлении инструкций. Для временного удобства я использовал [UIImage imageNamed:], чтобы захватить изображение. Он был правильно выделен и выпущен, но похоже, что сотрудничество IB с методом imageNamed: и / или кешем не идеально.

Тот факт, что, когда я пошел и взял новую копию изображения, я также дал ей новое имя, означал, что теперь изображение кнопки IB и изображение временного заполнителя больше не были одним и тем же изображением. .

Я вернулся к резервной копии моего проекта пару дней назад, чтобы проверить свою теорию. Все, что я сделал, это сказал представлению инструкций использовать другое изображение-заполнитель. Сбои прекратились.

Значит, это, вероятно, ошибка SDK. Не должно быть никаких причин не использовать изображение в IB, а также использовать то же изображение в другом месте с помощью imageNamed :. Если в один прекрасный день мне станет скучно или скучно, возможно, я сведу это в пример проекта и отправлю на радар Apple.

person Rob    schedule 16.10.2009
comment
Мне это кажется супер, супер маловероятным - я думаю, что многие люди все время используют образные имена и IB. Хотя было бы интересно потестить. - person Kendall Helmstetter Gelner; 17.10.2009

Как ваш файл XIB связан с вашим представлением? Какие IBOutlets вы определили? Я действительно сомневаюсь, что вы решили свою проблему так, как вы описываете.

person Kendall Helmstetter Gelner    schedule 16.10.2009
comment
Я согласен с тем, что не похоже, что это должно быть причиной (или решением) проблемы, но с тех пор, как я это сделал, он ни разу не разбился. Я, вероятно, закончил примерно 50 попыток воспроизвести аварию, прежде чем убедился в достаточной мере, чтобы двигаться дальше. До внесения изменений мне удавалось вызывать сбой каждые 2–4 раза, когда я пытался. пожать плечами. - person Rob; 16.10.2009
comment
(Конечно, это еще не все ... см. Обновление в моем полном ответе.) - person Rob; 17.10.2009