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?

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

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


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.