2013-03-01 5 views
8

Кажется, что UIPageViewController удерживает начальный контроллер содержимого навсегда. Например:Утечка памяти UIPageViewController

DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard]; 
NSArray *viewControllers = @[startingViewController]; 
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL]; 
self.pageViewController.dataSource = self.modelController; 

startingViewController никогда не освобождается, пока сам pageViewController не выпустили.

Чтобы воспроизвести эту ошибку, просто создайте новый проект в XCode, используя шаблон приложения на основе страницы. И добавить 3 строки кода в DataViewController.m

@property NSInteger debugIndex; // file scope 
NSLog(@"DataViewController[%d] created", self.debugIndex); // in viewDidLoad 
NSLog(@"DataViewController[%d] dealloc", self.debugIndex); // in dealloc 

И при прокрутке демо App в вертикальной ориентации, вы будете получать журналы, как это:

DataViewController[0] created 
DataViewController[1] created 
DataViewController[2] created 
DataViewController[1] dealloc 
DataViewController[3] created 
DataViewController[2] dealloc 
DataViewController[4] created 
DataViewController[3] dealloc 
DataViewController[5] created 
DataViewController[4] dealloc 
DataViewController[6] created 
DataViewController[5] dealloc 

DataViewController [0] является никогда не освобождается.

Любые идеи об этом? Спасибо!

+0

ли вы когда-нибудь найти решение этой проблемы с ARC? –

ответ

-1

У меня была та же проблема и решена следующим образом:

[startingViewController release];, где конечная точка инициализации.

тогда первый ViewController будет освобожден.

+2

Но я использую ARC ... –

3

Вы используете переходStyle UIPageViewControllerTransitionStyleScroll? Я столкнулся с той же или подобной проблемой, которая, казалось, исчезла при использовании анимации завивки страниц.

Проблема была усугублена для меня, потому что я позволял UISliderBar устанавливать позицию в контенте. Поэтому при изменении UISliderBar я вызывал setViewControllers: direction: animated: completion: что вызвало все больше ссылок на диспетчер ссылок, чтобы «застрять» в моем UIPageViewController.

Я также использую ARC. Я не нашел приемлемого способа заставить UIPageViewController отпустить дополнительные ссылки контроллера просмотра. Вероятно, я либо воспользуюсь переходом на curl страницы, либо реализую свой собственный эквивалент UIPageViewController, используя UIScrollView с включенным пейджингом, поэтому я могу управлять своим собственным кешем контроллера View вместо того, чтобы полагаться на управление прерываниями UIPageViewController.

+0

Да, я использую стиль прокрутки. Я выполнил свой собственный PageView, поскольку ни одна из версий с открытым исходным кодом не соответствует моим требованиям. –

3

Я не уверен, что у вас все еще есть проблема, но у меня была та же проблема, и я нашел решение.

Я не знаю причину, но она работает.

Я устанавливаю первый viewController сразу после addSubview, а не до addChlidViewController.

-(void)settingPageViewController{ 
if (!self.pageViewController) { 
    self.pageViewController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; 
    self.pageViewController.delegate = self; 
    self.pageViewController.dataSource = self; 
    [self addChildViewController:self.pageViewController]; 
    [self.pageViewController didMoveToParentViewController:self]; 
    [self.containerView addSubview:self.pageViewController.view]; 
    [self.pageViewController setViewControllers:@[[self viewcontrollerAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; 
}  
} 

и первый viewController будет dealloc в нужное время.

также, я нашел, если вызов

 [self.pageViewController setViewControllers:@[[self viewcontrollerAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished){ 
     NSLog(@"finished : %d",finished); 
    }]; 

Перед addSubView и блок завершения не будет звонить.

, и я считаю, что этот блок является причиной того, почему первый viewController не удалил.

Я пойду выяснить, почему он не обратного вызова, а также улучшить ответ ~

ура

+0

Этот должен быть принят. –

+0

Да, это единственное решение, которое сработало и для меня! В документации не указано это как требование, но это был единственный способ получить вызов dealloc. –

1

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

1) была циклическая ссылкой между UIPageViewController и UIViewController, который был представлен (это было зафиксировано путем изменения свойств слабого от сильного в обеих классах)

2) и основное исправление состояло в изменении

[self setViewControllers:@[initialDetailsViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; 

в

__weak __typeof__(self) weakSelf = self; 
    [weakSelf setViewControllers:@[initialDetailsViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; 

Я надеюсь, что это помогает кто-то

0

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

+0

Вы можете помочь мне с фрагментом кода? Заранее спасибо. – Ashik

Смежные вопросы