14

Sono in qualche modo poco chiaro sui modelli di proprietà degli oggetti richiesti per le seguenti istanze. Quando il mio UIViewController presenta un controller popover, un foglio azioni, o un altro controller vista come modale, sono obbligato a rimanere su un riferimento mantenuto a quel controller figlio fino a quando non viene rimosso?Mantieni/rilascia pattern per UIPopoverController, UIActionSheet e controller di visualizzazione modali?

In altre parole, le seguenti righe di codice "trasferiscono" effettivamente la proprietà o no?

[aPopoverController presentPopoverFromBarButtonItem:someButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO]; 

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO]; 

[aViewController presentModalViewController:someOtherViewController animated:YES]; 

Qualcuno può indicarmi una documentazione esplicita su questo argomento?

risposta

26

UIPopoverViewController ha una gestione/gestione della memoria leggermente diversa. Presentare un popover non mantiene la memoria, quindi non puoi trasferire la proprietà del tuo popviewcontroller all'oggetto che presenta.

Per evitare perdita di memoria, è necessario adottare l'UIPopoverControllerDelegate e implementare il metodo DidDismissPopOver come segue:

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [popoverController release]; 
} 

In questo modo, è possibile alloc sicuro e presentare un Popover:

-(void)showSearch:(id)sender { 
    SearchViewController *searchVC = [[SearchViewController alloc] init]; 
    UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:searchVC]; 
    popVC.delegate = self; 
    [popVC setPopoverContentSize:CGSizeMake(320, 100)]; 
    [popVC presentPopoverFromRect:CGRectMake(200, 200, 320, 100) inView:self.view permittedArrowDirections:0 animated:YES]; 
    [searchVC release]; 
} 
+1

Attenzione, searchVC perde se lo fai in questo modo. Aggiungi un autorelease. – steipete

+0

Sì, searchVC è trapelato. Invece di un'autorelease, funzionerà anche una semplice versione. Aggiungere questo per l'ultima riga: '[rilascio searchVC];' –

+1

come documentazione per 'popoverControllerDidDismissPopover:' dice: _ "Il controller popover non significa chiamare questo metodo in risposta agli inviti programmatiche al dismissPopoverAnimated: metodo se si. chiudere il popover a livello di codice, è necessario eseguire qualsiasi azione di pulizia immediatamente dopo aver chiamato il metodo dismissPopoverAnimated: "_. Quindi, se si utilizza 'dismissPopoverAnimated:' è necessario chiamare anche la versione successiva, altrimenti si otterrà una perdita. – ivanzoid

1

La presentazione di un controller della vista modale mantiene UIViewController. Questo in realtà non è chiaro dai documenti. Tuttavia, ho provato utilizzando il seguente codice ...

NSLog(@"BEFORE %d", [self.setupViewController retainCount]); 
[self.navigationController presentModalViewController:self.setupViewController animated:YES]; 
NSLog(@"AFTER %d", [self.setupViewController retainCount]); 

Il self.setupViewController è già mantenuta a livello locale, ma presentandolo in uscita il seguente:

2010-05-19 10:07:36.687 LocateMe[27716:207] BEFORE 1 
2010-05-19 10:07:36.762 LocateMe[27716:207] AFTER 3 

Così è stato probabilmente trattenuto nel proprietà modalViewController locale, nonché nella gerarchia della vista. Il licenziamento compenserà questi.

Quindi la linea di fondo è, conservarla se si desidera controllarla direttamente, ma non è necessario.

EDIT - Giusto per essere chiari, il corretta modello è quello di mantenere sempre un oggetto se viene impostato dall'utente come suo delegato. Questo perché dovresti impostare il delegato su zero nel tuo dealloc per sicurezza. In pratica, però, un controllore modale verrà sempre eliminato prima di dealloc, quindi non è un problema. Noterai che Apple infrange anche questa regola in [UIView setAnimationDelegate:], che in realtà mantiene il delegato impostato.

+0

lo farei Inoltre, aggiungo che gran parte del codice di esempio di Apple inizializza un UIViewController, lo presenta in modo modale e quindi lo rilascia. Guarda l'esempio AddMusic. – DougW

+0

Lo stesso vale per i popover e i fogli di azione? –

+0

Sì, è possibile avviare UIAlertView e quindi rilasciarlo. Oppure puoi mantenerlo se vuoi fare qualcosa. In entrambi i casi va bene, assicurati di bilanciare i tuoi ritegni/rilasci. – DougW