Как мне убедиться, что popToRootViewControllerAnimated работает? - PullRequest
0 голосов
/ 23 марта 2012

У меня есть UINavigationController, который выдвигает на него три представления, когда пользователь циклически перебирает страницы (всегда в одном и том же порядке) - я назову их views0, 1 и 2, чтобы выровнять индикаторы контроллера навигации.Представления создаются в раскадровке.

Когда последовательность представлений завершена и пользователь хочет вернуться к началу, я использую popToRootViewControllerAnimated: YES в ответ на нажатие кнопки, и пользовательский интерфейс соответствующим образом возвращается кview0.Тем не менее, я иногда получаю «фантомные» записи в журнале в ответ на уведомления для всего приложения, если я повторяю цикл снова, давая понять, что view1 (среднее представление) никогда не был полностью освобожден.Я использую ARC в xcode 4.2.1 только с кодом iOS5 +, поэтому ARC должен очень хорошо позаботиться о вещах.

Я видел несколько постов, в которых говорилось, что ARC не освобождает просмотры, чей счетчик ссылокне опустился до 0, поэтому я сделал все, что мог, чтобы установить свойства равными nil, когда закончил, и двойная проверка показывает, что ничего не осталось, когда я нажимаю на окончательный вид ... и ничего за пределами NavigationControllerссылки view1 (что я знаю).Профилирование приложения на наличие зомби и утечек памяти ничего не дает.

Как я могу просмотреть / log / debug то, что еще может ссылаться на представление?Как я могу сказать, что он был успешно освобожден, не помещая в него вещи, которые могли бы предотвратить сделку?

Мой код (по сути) выглядит следующим образом:

view0 толкает к view1 с помощью «Push»"segue in storyboard.

View 1:

- (void)viewDidLoad
    { 
    [super viewDidLoad];

    /* register as observer for some notifications */
    /* set properties and format an image or two */
    }

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

/* start some animation here */
}


- (void) receiveNotification {

NSObject *newObject = [[NSObject alloc] init];

[newObject doStuff];

/* Remove notification observers */

}


- (void)objectDelegateMethod:(NSDictionary *) dataReturned {

/* do stuff with dataReturned */
self.propertyName = dataReturned;

[self performSegueWithIdentifier:@"AllDone" sender:self];

}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

if ([[segue identifier] isEqualToString:@"AllDone"])
{

View2ViewController *destinationView = [segue destinationViewController];

destinationView.propertyMagic = self.propertyName;

[self setPropertyName:nil];
//do same with all other properties

}

View2:

- (void)viewDidLoad
{

/* display things based on self.propertyMagic */

}


- (IBAction)userStartsOverButton:(id)sender {

[self.navigationController popToRootViewControllerAnimated:YES];

}

Учитывая приведенную выше (грубую) структуру, если я не удаляю view1 какнаблюдатель уведомлений, он продолжает отвечать и выводить в журнал, хотя я не могу понять, почему он не был освобожден.Даже когда я действительно удаляю наблюдателей, использование памяти продолжает увеличиваться по мере того, как я циклически запускаю приложение и в конечном итоге происходит сбой (без утечек в инструментах).

Как мне это выяснить?

Ответы [ 2 ]

1 голос
/ 23 марта 2012

Если у вас есть утечки и зомби, то ... у вас, вероятно, нет утечек или перепусков.

Чтобы "увидеть", что сделка произошла в ARC, вы можете добавить пустую запись dealloc в свой класс:

- (void)dealloc
{
    NSLog(@"%s:%d", __func__, __LINE__);
}
0 голосов
/ 23 марта 2012

Вы могли бы проверить, есть ли у любого другого объекта указатель (strong) на view1.Если это так, вы можете изменить его на (weak) или просто не хранить ссылку на него.(Ищите возможный цикл сохранения между view0 и view1 и между view1 и view2, возможно, они хранят ссылки друг на друга).

ARC будет освобождать объект, если он больше не принадлежит ни одному другому объекту.Поэтому вы также можете попробовать переписать метод -popToRootViewControllerAnimated: в view0 и вызвать что-то вроде:

self.view1 = nil;

Если view0 - единственный объект, сохраняющий ссылку на view1, view1 должен быть освобожден (освобожден).

...