110

Le aseguro que sí busqué una respuesta en SO para mi pregunta, pero ninguna de ellas fue útil. Aquí me dieron un código simple que debe presentar un UIImagePickerController dentro de un UIPopoverController:UIPopovercontroller dealloc alcanzado mientras popover aún es visible

-(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]; 
} 

Ahora, incluso desde la primera vez que tengo tiempo ... [UIPopoveController dealloc] alcanzados de error y el programa se bloquea. No estoy reteniendo, reenviando o lanzando automáticamente como ARC. ¿Hay alguna consideración especial con UIPopoverControllers cuando se beneficia de ARC?

Respuesta

203

UIPopoverControllers siempre deben mantenerse en una variable de instancia. Es una buena práctica crear una propiedad fuerte para ella.

ACTUALIZACIÓN:

A partir de iOS 8 debería utilizar UIPopoverPresentationController. Entonces no necesita mantener una referencia al popover porque es administrado por el controlador de presentación.

ejemplo de código (funciona tanto en el iPhone y el 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, ya veo. ¿Pero no es esto como un UIAlertView? Nunca tengo un ivar para eso, solo lo instalo donde sea que lo necesite, lo demuestro y luego [solía] liberarlo. ¿En qué es diferente popovercontroller? –

+17

@Mikayil La vista de alerta se conserva mediante su supervista (como todas las vistas), pero popoverController no es una vista, por lo que no tiene una supervista, por lo que no será retenida por nadie si no la conserva (o almacenarlo en una variable fuerte que tiene un alcance que es más largo que el método actual, por ejemplo, un iVar). – fzwo

+1

Pero todavía estoy confundido acerca del conteo de retención del UIPopoverController. Porque puse una marca antes de asignar e iniciar uno. Y solo si es nulo, puedo asignar uno nuevo. Pero después de asignarlo por primera vez, nunca lo entiendo. Quiero decir que llamo a un método una vez. Ahí asigné e inicié mi ivar. Y la próxima vez cuando vuelvo a llamar a ese método esta vez, encuentro que mi ivar ya está asignado. Si ARC se ocupa de esto, ¿cuándo lo libera? ¿O lo libera automáticamente? –

11

Cuando la función sale, no hay otra referencia al controlador de popover, por lo que se desasigna demasiado pronto.

Pruebe agregarlo como miembro de su clase en su lugar.

Tim

+0

¿Todavía no debería poder verlo primero antes de que se desasigna? –

10

Adición de lo @ phix23 respondió, crear * propiedad poc así:

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

y luego cambiar

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

para

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

No tiene para ponerlo en tu archivo .h Eso lo haría público y, a menos que lo desee, simplemente conviértalo en una propiedad de su archivo .m. –

+0

Tuve un problema similar en iOS 7 y resolví esta solución. – dobiho

Cuestiones relacionadas