Osiągnięto dealloc kontrolera UIPopover, podczas gdy popover jest nadal widoczny

111

Zapewniam, że szukałem odpowiedzi w SO na moje pytanie, ale żadna z nich nie była pomocna. Tutaj mam prosty kod, który powinien przedstawiać UIImagePickerControllerw a UIPopoverController:

-(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 już od pierwszego razu [UIPopoveController dealloc]dotarłem podczas ... błędu i awarii programu. Nie robię żadnych zachowań, zwolnień ani autoreleasów zgodnie z ARC. Czy należy zwrócić szczególną uwagę na UIPopoverControllerskorzyści z ARC?

Mikayil Abdullayev
źródło

Odpowiedzi:

203

UIPopoverControllers powinny zawsze znajdować się w zmiennej instancji. Dobrą praktyką jest stworzenie dla niego silnej właściwości.

AKTUALIZACJA:

Od iOS 8 powinieneś używać UIPopoverPresentationController. Wtedy nie musisz zachowywać odniesienia do popover, ponieważ jest zarządzany przez kontroler prezentacji.

Przykład kodu (działa zarówno na iPhonie, jak i iPadzie):

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];
Felix
źródło
1
Rozumiem. Ale czy to nie jest jak UIAlertView? Nigdy nie mam do tego ivar, po prostu umieszczam go tam, gdzie potrzebuję, pokazuję, a następnie [zwykłem] wypuszczać. Czym różni się kontroler popover?
Mikayil Abdullayev
17
@Mikayil AlertView jest zachowywany przez swój superview (jak wszystkie widoki), ale popoverController nie jest widokiem, więc nie ma superviewu, więc nie zostanie zachowany przez nikogo, jeśli go nie zachowacie (lub przechowywać go w silnej zmiennej, która ma zasięg dłuższy niż bieżąca metoda - na przykład iVar).
fzwo
1
Ale nadal jestem zdezorientowany co do liczby zachowań kontrolera UIPopoverController. Ponieważ wystawiam czek przed przydzieleniem i zainicjowaniem. I tylko jeśli jest zerowy, przydzielam nowy. Ale po przydzieleniu go po raz pierwszy nigdy nie uzyskałem zera. Chodzi mi o to, że dzwonię kiedyś do metody. Tam przydzielam i uruchamiam mój ivar. Następnym razem, gdy ponownie wywołam tę metodę, tym razem stwierdzam, że mój ivar jest już przydzielony. Jeśli ARC się tym zajmie, to kiedy to zwolni. Czy może to automatycznie się udostępnia?
Mikayil Abdullayev
@Mikayil ivary są uwalniane przez ARC, gdy obiekt jest zwalniany lub gdy ustawisz je na zero
Felix
ale nie wspomnieli o tym w dokumentacji, w sekcji Jak używać używają zmiennej lokalnej
Amit Battan.
11

Kiedy funkcja kończy działanie, nie ma innego odniesienia do kontrolera popover, więc jest on zwalniany zbyt wcześnie.

Zamiast tego spróbuj dodać go jako członka swojej klasy.

Tim

tarmes
źródło
Czy nadal nie powinienem być w stanie go najpierw zobaczyć, zanim zostanie zwolniony?
Mikayil Abdullayev
10

Dodając odpowiedź @ phix23, utwórz właściwość * poc w następujący sposób:

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

a potem zmienić

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

dla

self.poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];
orafaelreis
źródło
11
Nie musisz umieszczać go w swoim pliku .h. To uczyniłoby go publicznym i jeśli tego nie chcesz, po prostu ustaw go jako właściwość w swoim pliku .m.
Joshua Dance