2013-03-01 27 views
8

Wygląda na to, że UIPageViewController na zawsze trzyma kontroler początkowego widoku treści. Na przykład:UIPageViewController wyciek pamięci

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 nigdy nie jest zwolniony, dopóki sama pageViewController zwolniony.

Aby odtworzyć ten błąd, wystarczy utworzyć nowy projekt w Xcode za pomocą strony-Based Application szablon. I dodać 3 linie kodu w DataViewController.m

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

i podczas przewijania demo aplikacji w orientacji pionowej, dostaniesz logi jak to:

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] jest nigdy nie anulowane.

Wszelkie pomysły na ten temat? Dzięki!

+0

Czy kiedykolwiek znaleźć rozwiązanie tego z ARC? –

Odpowiedz

-1

miałem sam problem i rozwiązać następujące:

[startingViewController release]; gdzie punkt końcowy inicjalizacji.

następnie pierwszy ViewController zostanie zwolniony.

+2

Ale używam ARC ... –

3

Czy używasz metody transitionStyle UIPageViewControllerTransitionStyleScroll? Napotkałem ten sam lub podobny problem, który wydawał się zanikać, gdy zamiast tego używa się animacji zwijania strony.

Problem był potęgowany dla mnie, bo ja umożliwiając UISliderBar ustawić pozycję w treści. Tak więc przy zmianie paska UISliderBar wywołałem setViewControllers: direction: animated: completion: co spowodowało, że coraz więcej odwołań kontrolera widoku dostało "utknięcie" w moim UIPageViewController.

Używam również ARC. Nie znalazłem dopuszczalnego sposobu na wymuszenie od UIPageViewController zwolnienia dodatkowych odwołań kontrolera widoku. Prawdopodobnie albo zakończę korzystanie z przejścia w curl strony, albo wprowadzę własny odpowiednik UIPageViewController za pomocą UIScrollView z włączoną obsługą stronicowania, dzięki czemu będę mógł zarządzać własną pamięcią podręczną kontrolera widoku, zamiast polegać na zarządzaniu uszkodzonym kontrolerem widoku UIPageViewController.

+0

Tak, używam stylu przewijania. Zaimplementowałem własną odsłonę strony, ponieważ żadna z implementacji open source nie spełnia moich wymagań. –

3

Nie jestem pewien, czy nadal masz problem, ale miałem ten sam problem i znalazłem rozwiązanie.

Nie znam przyczyny, ale działa.

Ustawiam pierwszy viewController zaraz po addSubview, a nie przed 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]; 
}  
} 

i pierwszy widokController dealloc we właściwym czasie.

również znalazłem jeśli wezwanie

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

przed addSubView a blok ukończenie nie zadzwoni.

i myślę, że ten blok jest powodem, dla którego pierwszy viewController nie dealloc.

Pójdę dowiedzieć się, dlaczego nie callback i poprawić odpowiedź ~

wiwaty

+0

Ten powinien zostać przyjęty. –

+0

Tak, to jedyne rozwiązanie, które zadziałało również dla mnie! Dokumentacja nie określa tego jako wymogu, ale był to jedyny sposób, aby uzyskać wywołanie dealloc. –

1

Po kilku próbach, aby dowiedzieć się, co dzieje się na podobny problem, zauważyłem, że w w moim projekcie wystąpiły 2 powody, które spowodowały problem z zatrzymaniem i spowodowały, że UIPageViewController został na zawsze zachowany.

1) nie był okrągły odniesienia pomiędzy UIPageViewController i UIViewController który został przedstawiony (ten został rozwiązany poprzez zmianę właściwości osłabiony silny obu klas)

2) a głównym poprawka polegał na zmianie

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

do

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

mam nadzieję, że to pomoże ktoś

0

sam problem tutaj postanowiłem go trzymając moją początkową viewController w zmiennej i zamiast tworzyć ten sam VC szczególności PageIndex ja po prostu używać go

+0

możesz mi pomóc z fragmentem kodu? Z góry dziękuję. – Ashik