после отклонения модального представления родительское представление кажется освобожденным? - PullRequest
2 голосов
/ 12 июля 2010

Я пишу приложение для iPhone. Начиная с контроллера представления в стеке навигации [называемого EditCreatorController], я представляю пользовательский контроллер модального представления [называемый BMSStringPickerController]. Я создал протокол делегирования и т. Д. В соответствии с рекомендациями Apple для передачи данных обратно в первое представление и использования этого представления для отклонения модального представления. Я даже получаю ожидаемые данные от модального контроллера и могу их просто проигнорировать. Проблема заключается в том, что практически любое действие, которое я предпринимаю на исходном контроллере представления, приводит к ошибкам отладчика, таким как

- [EditCreatorController executeSelector: withObject: withObject:]: сообщение отправлено освобожденному экземпляру 0x3a647f0

или

- [EditCreatorController tableView: willSelectRowAtIndexPath:]: сообщение отправлено освобожденному экземпляру 0x3c12c40

Другими словами, кажется, что оригинальный контроллер вида испарился во время показа модального представления. Это верно независимо от того, какой из двух делегатов будет вызван.

Вот код из родительского контроллера, который вызывает модальное представление:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 1) { // selection on creator type row

    // create a string picker to choose new creator type from list
    BMSStringPickerController *picker = [[BMSStringPickerController alloc] initWithNibName:@"BMSStringPickerController" bundle:nil];
    picker.delegate = self;
    picker.stringChoices = [NSArray arrayWithObjects:@"composer", @"lyricist", @"arranger", @"original artist", @"other", nil];
    picker.currentChoice = creator.type;
    picker.title = @"Creator Type";

    // wrap it in a nav controller so we can get tile bar etc. (from VC prog guide p. 93)
    UINavigationController *newNavigationController = [[UINavigationController alloc]
                                                    initWithRootViewController:picker];

    [self.navigationController presentModalViewController:newNavigationController animated:YES];
    [newNavigationController release];
    [picker release];

 }
}

А вот и обратные вызовы делегатов:

 - (void)stringPickerController:(BMSStringPickerController *)picker didPickString:(NSString *)string {
NSLog(@"received string back: %@", string);
typeLabel.text = string; // only change the label for now; object only changes if done button pressed
[self.tableView reloadData];
[self dismissModalViewControllerAnimated:YES];
}

- (void)stringPickerControllerDidCancel:(BMSStringPickerController *)picker {
NSLog(@"picker cancelled");
[self dismissModalViewControllerAnimated:YES];
}

Еще одна странная вещь (возможно, подсказка) заключается в том, что хотя я получаю сообщение NSLog «полученная строка назад» и назначаю его для typeLabel.text (typeLabel - это IBOutlet для метки в моем табличном представлении), она там никогда не появляется даже при перезагрузке стола.

У кого-нибудь есть идеи?

Ответы [ 3 ]

2 голосов
/ 12 июля 2010

Может быть, вы выпустили delegate в dealloc из BMSStringPickerController?

1 голос
/ 12 июля 2010

Поведение по умолчанию при наличии предупреждения о памяти - отключение представления всех невидимых контроллеров представления.Поэтому, если в вашем контроллере модального представления было предупреждение о памяти, его родительский контроллер представления мог бы выгружать свое представление.

Когда это происходит, viewDidUnload вызывается на контроллере представления, чтобы вы могли освободить любые ссылки, которые вы удерживаете в представлении.Если у вас есть ссылки, которые вы не сохранили, они станут недействительными при выгрузке представления.Может быть, это происходит в вашем случае?

Подробнее см. В разделе Справочник по управлению UIViewController Управление памятью .Метод UIViewController didReceiveMemoryWarning: освобождает представление, если представление в данный момент не видно, и затем вызывает viewDidUnload.

1 голос
/ 12 июля 2010

Возможно, это не решит вашу проблему, но я предлагаю сказать сборщику о том, что он должен отстраниться (в методах делегата), позволяя цепочке респондента правильно обрабатывать отклонение:

[picker dismissModalViewControllerAnimated:YES];
...