110

Zapewniam, że szukałem odpowiedzi w SO na moje pytanie, ale żaden z nich nie był pomocny. Tutaj mam prosty kod, który należy przedstawić UIImagePickerController W ciągu UIPopoverController:UIPopovercontroller dealloc osiągnięty, podczas gdy popover jest nadal widoczny

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

Teraz, nawet po raz pierwszy uzyskać [UIPopoveController dealloc] gdy nadejdzie ... wywala błąd i program. Nie robię żadnych retain, relase lub autoreleases według ARC. Czy przy korzystaniu z ARC istnieje szczególna uwaga dotycząca UIPopoverControllers?

Odpowiedz

203

UIPopoverControllers powinny być zawsze przechowywane w zmiennej instancji. Dobrą praktyką jest tworzenie silnej własności.

UPDATE:

Jako iOS 8 należy używać UIPopoverPresentationController. Wtedy nie musisz utrzymywać odniesienia do popover, ponieważ jest on zarządzany przez kontroler prezentacji.

przykład kod (działa zarówno na iPhone i 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

Och, rozumiem. Ale czy to nie jest jak UIAlertView? Nigdy nie mam na to Ivara, po prostu przydzielaję go wszędzie tam, gdzie potrzebuję, pokaż go, a następnie [zwalniam]. Czym różni się kontroler popover? –

+17

@Mikayil AlertView jest zachowywany przez jego widok (tak jak wszystkie widoki), ale kontroler popoverController nie jest widokiem, więc nie ma podglądu, więc nikt go nie zatrzyma, jeśli go nie zatrzymasz (lub przechowuj go w silnej zmiennej, której zasięg jest dłuższy niż bieżąca metoda - na przykład iVar). – fzwo

+1

Ale nadal jestem zdezorientowany co do zachowania licznika UIPopoverController. Ponieważ wystawiłem czek, zanim go przydzieliłem i zainicjowałem. I tylko jeśli jest zero, przydzielam nowy. Ale po przydzieleniu go po raz pierwszy nigdy go nie dostaję. Chodzi mi o to, że raz nazywam metodę. Tam przydzielam i inicjuję mój ivar. I następnym razem, gdy ponownie nazywam tę metodę tym razem, znajduję już przydzielony mój ivar. Jeśli ARC zajmie się tym, to kiedy go zwolni. Czy może go autoreasować? –

11

Po zamknięciu funkcji nie ma innych odniesień do kontrolera typu popover, więc jest on zwalniany za wcześnie.

Spróbuj dodać go jako członka swojej klasy.

Tim

+0

Czy nie powinienem nadal widzieć go wcześniej, zanim zostanie zwolniony? –

10

Dodawanie co @ phix23 odpowiedział utworzyć * nieruchomość poc tak:

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

a następnie zmienić

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

dla

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

Nie masz umieścić go w pliku .h. To sprawi, że będzie to publiczne i jeśli tego nie chcesz, po prostu ustaw je jako własność w pliku .m. –

+0

Miałem ten sam problem w iOS 7 i rozwiązałem to rozwiązanie. – dobiho