2013-03-01 6 views
8

Sembra che UIPageViewController mantenga per sempre il controller di visualizzazione del contenuto iniziale. Per esempio:Perdita di memoria 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; 

Il startingViewController non è mai rilasciato fino a quando il pageViewController sé rilasciato.

Per riprodurre questo errore, è sufficiente creare un nuovo progetto in XCode utilizzando il modello di applicazione pagina. E aggiungere 3 righe di codice in DataViewController.m

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

E quando si scorre la demo App in orientamento verticale, si otterrà i registri come questo:

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] è mai rilasciato.

Qualche idea al riguardo? Grazie!

+0

Hai mai trovare una soluzione a questo con ARC? –

risposta

-1

Ho avuto lo stesso problema e risolto il seguente:

[startingViewController release]; dove il punto finale di inizializzazione.

quindi il primo ViewController sarà deallocato.

+2

Ma sto usando ARC ... –

3

Si sta utilizzando transitionStyle UIPageViewControllerTransitionStyleScroll? Ho riscontrato lo stesso problema o un problema simile che sembrava scomparire quando si utilizzavano le animazioni di arricciatura di pagina.

Il problema è stato aggravato per me perché stavo consentendo a UISliderBar di impostare la posizione nel contenuto. Quindi, al cambio di UISliderBar, stavo chiamando setViewControllers: direction: animated: completion: che ha causato sempre più riferimenti al controller di visualizzazione per rimanere "bloccati" nel mio UIPageViewController.

Sto anche usando ARC. Non ho trovato un modo accettabile per forzare UIPageViewController a rilasciare i riferimenti aggiuntivi del controller di visualizzazione. Probabilmente finirò per utilizzare la transizione del ricciolo della pagina o implementare il mio equivalente UIPageViewController utilizzando un UIScrollView con il paging abilitato in modo da poter gestire la mia cache del controller di visualizzazione invece di affidarmi alla gestione interrotta del controller della vista di UIPageViewController.

+0

Sì, sto usando lo stile di scorrimento. Ho implementato il mio PageView in quanto nessuna implementazione open source soddisfa i miei requisiti. –

3

Non sono sicuro che il problema si sia ancora verificato, ma ho riscontrato lo stesso problema e ho trovato la soluzione.

Non conosco il motivo, ma funziona.

Sto impostando il primo viewController subito dopo addSubview, anziché prima dello 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]; 
}  
} 

e la prima viewController sarà dealloc nel momento giusto.

Inoltre, ho trovato se chiamata

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

prima addSubView e il blocco di completamento non chiameranno.

e ritengo che questo blocco sia la ragione per cui il primo viewController non ha dealloc.

andrò scoprire perché non ha richiamata, e migliorare la risposta ~

applausi

+0

Questo dovrebbe essere accettato. –

+0

Sì, questa è l'unica soluzione che ha funzionato anche per me! La documentazione non afferma questo come un requisito, ma questo era l'unico modo per me per ottenere il dealloc da chiamare. –

1

Dopo qualche tentativo di capire cosa stava succedendo su un problema simile, ho notato che in il mio progetto ci sono stati 2 motivi che hanno causato un problema di conservazione e hanno portato a mantenere UIPageViewController per sempre.

1) c'era un riferimento circolare tra l'UIPageViewController e UIViewController che è stato presentato (questo è stato risolto modificando le proprietà di debole proveniente forte in entrambe le classi)

2) e la correzione principale consisteva nel cambiare

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

a

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

Spero che questo aiuta qualcuno

0

stesso problema qui ho risolto facendo mantenere il mio viewController iniziale nella variabile e invece di creare la stessa vc su particolari pageIndex ho appena riutilizzarlo

+0

puoi aiutarmi con lo snippet di codice? Grazie in anticipo. – Ashik