2

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

- [EditCreatorController performSelector: 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 для метки в моем представлении таблицы), он никогда не появляется там, даже при перезагрузке таблицы.

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

ответ

2

Возможно, вы отпустите delegate в dealloc от BMSStringPickerController?

+0

Bingo! Спасибо, Майкл. Так кроваво очевидно, как только вы это указали! Это вызывает вопрос: если я не выпущу его там, у меня есть утечка памяти сейчас? Казалось бы, у моего первоначального вызова (делегата) теперь есть дополнительное удержание.Или, может быть, нет - объявление в объекте picker: @property (присвоить) id делегат; Так как это назначение не сохраняется, я полагаю, когда сборщик уходит через звонок, чтобы отменитьModal ... все чистое снова по памяти? (Понятно, что я все еще углубляю свое понимание управления памятью obj-c!) :-) –

+0

Вы правы - если свойство не отмечено «сохранить» или «скопировать», оно не сохраняется, и нет необходимости выпускать Это. Вам лучше установить нуль ... –

1

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

[picker dismissModalViewControllerAnimated:YES]; 
1

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

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

Подробнее см. В разделе UIViewController reference Memory Management. Метод UIViewController didReceiveMemoryWarning: освобождает представление, если вид не отображается в данный момент, а затем вызывает viewDidUnload.