110

Ti assicuro che ho cercato una risposta in SO per la mia domanda ma nessuno di loro è stato utile. Qui ho avuto un semplice codice che dovrebbe presentare una UIImagePickerController all'interno di un UIPopoverController:Dealloc UIPopovontroller raggiunto mentre il popover è ancora visibile

-(void)takePicture:(id)sender{ 
UIImagePickerController *picker=[[UIImagePickerController alloc] init]; 
picker.delegate=self; 
picker.sourceType=UIImagePickerControllerSourceTypeCamera; 
picker.allowsEditing=YES; 
UIPopoverController *poc=[[UIPopoverController alloc] 
          initWithContentViewController:picker]; 
[poc presentPopoverFromBarButtonItem:bbItem 
      permittedArrowDirections:UIPopoverArrowDirectionAny 
          animated:NO]; 
} 

Ora, anche dalla prima volta che ho [UIPopoveController dealloc] raggiunto quando ... errore ed il programma va in crash. Non sto mantenendo alcun fermo, relase o autorelease come da ARC. C'è qualche considerazione speciale con UIPopoverControllers quando si beneficia di ARC?

risposta

203

UIPopoverControllers devono sempre essere tenuti in una variabile di istanza. È una buona pratica creare una forte proprietà per questo.

UPDATE:

Come di iOS 8 si dovrebbe utilizzare UIPopoverPresentationController. Quindi non è necessario mantenere un riferimento al popover perché è gestito dal controller di presentazione.

Esempio di codice (funziona sia su iPhone e iPad):

UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 
picker.delegate = self; 
picker.sourceType = UIImagePickerControllerSourceTypeCamera; 
picker.allowsEditing = YES; 
picker.modalPresentationStyle = UIModalPresentationPopover; 
UIPopoverPresentationController* popoverPC = picker.popoverPresentationController; 
popoverPC.barButtonItem = bbItem; 
popoverPC.permittedArrowDirections = UIPopoverArrowDirectionAny; 
[self presentViewController:picker animated:YES completion:nil]; 
+1

Oh, capisco. Ma non è come un UIAlertView? Non ho mai avuto un ivar per questo, lo alloco init ovunque io abbia bisogno, lo mostro e poi [ho usato per] rilasciare. In che cosa è popovercontroller diverso? –

+17

@Mikayil L'alertView viene mantenuto dalla sua superview (come tutte le viste), ma il popoverController non è una vista, quindi non ha una superview, quindi non verrà conservato da nessuno se non lo si mantiene (o memorizzarlo in una variabile forte con un ambito più lungo del metodo corrente, ad esempio un iVar). – fzwo

+1

Ma sono ancora confuso riguardo al numero di conservazioni di UIPopoverController. Perché ho messo un assegno prima di allocarlo e iniziarne uno. E solo se è zero ne assegno uno nuovo. Ma dopo averlo assegnato per la prima volta non lo capisco mai. Voglio dire, chiamo un metodo una volta. Lì alloco e inizio il mio ivar. E la prossima volta che chiamerò di nuovo quel metodo questa volta trovo il mio ivar già allocato. Se ARC si occupa di questo, allora quando lo rilascia. O lo autorizza? –

11

Quando la funzione termina non ci sono altri riferimenti al controller popover, quindi è deallocato troppo presto.

Prova ad aggiungerlo come membro della tua classe.

Tim

+0

Non dovrei essere ancora in grado di vederlo prima che venga deallocato? –

10

Aggiunta cosa @ phix23 risposto, creare * proprietà POC in questo modo:

@property (nonatomic, retain) IBOutlet UIPopoverController *poc; 

e quindi modificare

UIPopoverController *poc = [[UIPopoverController alloc] 
          initWithContentViewController:picker]; 

per

self.poc = [[UIPopoverController alloc] 
          initWithContentViewController:picker]; 
+11

Non si dispone per metterlo nel tuo file .h. Ciò lo renderebbe pubblico e, a meno che tu non lo desideri, basta renderlo una proprietà nel tuo file .m. –

+0

Ho avuto lo stesso problema in iOS 7 e ho risolto questa soluzione. – dobiho

Problemi correlati