UINavigationController и управление памятью - PullRequest
1 голос
/ 12 мая 2010
- (void)launchSearch 
{
 EventsSearchViewController *searchController = [[EventsSearchViewController alloc] initWithNibName:@"EventsSearchView" bundle:nil];
 [self.navigationController pushViewController:searchController animated:YES];
 //[searchController release]; 
}

Обратите внимание, что [searchController release] закомментировано. Я понял, что нажатие searchController на контроллер навигации сохраняет его, и я должен освободить его из своего кода. В конце концов, я просто выделил / инициализировал его, и если я его не освобожу, он протечет.

С этой закомментированной строкой навигация работает отлично. Не закомментировав его, я могу нормально перейти к этому представлению, но при возврате вверх уровень падает с ошибкой *** -[CFArray release]: message sent to deallocated instance 0x443a9e0.

Что здесь происходит? NavigationController выпускает его для меня как-то, когда он выходит из поля зрения?

В шаблоне, который идет по шаблону UINavigationController в XCode, освобождается только что выдвинутый контроллер. Но когда я делаю это, это терпит неудачу.

--- EDIT ----

Итак, сегодня утром я сажусь, и это работает. Понятия не имею, почему. Вздох.

Взяв то, что, как я думал, я узнал, и применив это к другой части того же контроллера, я сделал следующее. Вчера у меня был этот код без заявлений о выпуске, потому что он не работал с ними. Итак, сегодня утром я добавил их для создания:

- (IBAction)switchView:(id)sender
{
    UISegmentedControl *seg = (UISegmentedControl *)sender;
    NSInteger choice = [seg selectedSegmentIndex];

    NSArray *array = [mainView subviews];
    UIView *oldView = [array objectAtIndex:0];
    [oldView removeFromSuperview];

    if (choice == 0) {
        tableController = [[EventsTableViewController alloc]
            initWithNibName:@"EventsTableView" bundle:nil];
            [mainView addSubview:tableController.view];
            [tableController release];
    }

    if (choice == 1) {
        calendarController = [[EventsCalendarViewController alloc]
            initWithNibName:@"EventsCalendarView" bundle:nil];
        [mainView addSubview:calendarController.view];
        [calendarController release];
    }
    if (choice == 2) {
        mapController = [[EventsMapViewController alloc]
            initWithNibName:@"EventsMapView" bundle:nil];
        [mainView addSubview:mapController.view];
        [mapController release];
    }
}

При такой настройке, когда я прихожу к представлению, основной портал моего представления заполнен представлением EventsTableViewController, я могу щелкнуть на mapView и calendarView, но когда я возвращаюсь назад к tableView, я умираю, потому что методы делегата таблицы вызываются на освобожденном экземпляре.

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

Ответы [ 3 ]

1 голос
/ 13 мая 2010

Ух ты, ребята. Большое спасибо за все ваши ответы - трагически я послал вас всех в ужасном гусе.

Мой NavigationView перемещается по NSArray объектов Event (локальные события искусства). В моем табличном представлении отображается подробный вид.

В моем подробном представлении содержится следующее:

-(void)loadEvent:(Event *)event
{
    thisEvent = event;          
}

И я вызываю это из моего табличного представления перед помещением подробного представления в стек навигации. thisEvent - это синтезированное свойство типа Event, и, так как он синтезирован, я покорно release сделал это в [dealloc].

Многие из вас уже видят проблему. При резервном копировании в табличное представление, когда я прокручиваю так, что отображается только что увиденное, он создает настраиваемую строку таблицы и, таким образом, получает свойство title из Event ...., которое я только что выпустил внутри детали. контроллер. Boom.

Я добавил retain к указанному выше методу loadEvent: и сбои исчезли.

Ничего из этого на самом деле не касалось того, как представления сохраняются и освобождаются navcontroller. Речь шла о случайном перевыпуске объектов данных, по которым я перемещаюсь. Часть того, что заставило меня это обнаружить, заключалась в том, что я зарегистрировал себя в [dealloc] каждого из этих контроллеров представления, и теперь я могу видеть, что они ведут себя именно так, как должны.

Спасибо! Я так люблю этот сайт.

0 голосов
/ 13 мая 2010

Похоже, EventsSearchViewController выделяет массив, а затем перевыпускает его, причем один из релизов, вероятно, находится в dealloc.

Если вы закомментируете release, ваш EventsSearchViewController никогда не освобождается (он утекает). Таким образом, ошибки, возникающие в результате его собственного dealloc, будут маскироваться, так как этот метод не будет вызываться. Освобождение контроллера - это правильно, но у вас есть еще одна ошибка в самом контроллере, которая появляется только во время освобождения.

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

0 голосов
/ 12 мая 2010

Я предполагаю, что ошибка кроется в инициализации EventsSearchViewController. Возвращает ли самовосстановление себя по ошибке?

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