UIPopovercontroller-Freigabe erreicht, solange Popover noch sichtbar ist

111

Ich versichere Ihnen, dass ich in SO nach einer Antwort auf meine Frage gesucht habe, aber keine davon war hilfreich. Hier habe ich einen einfachen Code, der ein UIImagePickerControllerinnerhalb eines 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];
}

Jetzt werde ich schon vom ersten Mal an [UIPopoveController dealloc]erreicht, während ... Fehler und das Programm abstürzt. Ich mache keine Retain-, Relase- oder Autoreleases gemäß ARC. Gibt es besondere Überlegungen, UIPopoverControllerswenn Sie von ARC profitieren?

Mikayil Abdullayev
quelle

Antworten:

203

UIPopoverController sollten immer in einer Instanzvariablen enthalten sein. Es ist eine gute Praxis, eine starke Eigenschaft dafür zu schaffen.

AKTUALISIEREN:

Ab iOS 8 sollten Sie verwenden UIPopoverPresentationController. Dann müssen Sie keinen Verweis auf das Popover behalten, da es vom Präsentationscontroller verwaltet wird.

Codebeispiel (funktioniert sowohl auf dem iPhone als auch auf dem 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];
Felix
quelle
1
Oh, ich verstehe. Aber ist das nicht wie ein UIAlertView? Ich habe nie ein Ivar dafür, ich ordne es einfach zu, wo immer ich es brauche, zeige es und veröffentliche es dann. In was unterscheidet sich Popovercontroller?
Mikayil Abdullayev
17
@Mikayil Die alertView wird von ihrer Übersicht beibehalten (wie alle Ansichten), aber der popoverController ist keine Ansicht, hat also keine Übersicht und wird von niemandem beibehalten, wenn Sie sie nicht beibehalten (oder Speichern Sie es in einer starken Variablen mit einem Bereich, der länger als die aktuelle Methode ist (z. B. ein iVar).
Zwei
1
Aber ich bin immer noch verwirrt über die Anzahl der Einbehaltungen des UIPopoverControllers. Weil ich einen Scheck stelle, bevor ich einen zuweise und initiiere. Und nur wenn es Null ist, ordne ich eine neue zu. Aber nachdem ich es zum ersten Mal zugewiesen habe, bekomme ich es nie gleich Null. Ich meine, ich rufe einmal eine Methode auf. Dort teile ich meinen Ivar zu und initiiere ihn. Und wenn ich diese Methode das nächste Mal wieder aufrufe, finde ich meinen Ivar bereits zugewiesen. Wenn ARC sich darum kümmert, wann gibt es es frei. Oder gibt es es automatisch frei?
Mikayil Abdullayev
@ Mikayil ivars werden von ARC freigegeben, wenn das Objekt freigegeben wird oder wenn Sie sie auf null setzen
Felix
aber sie haben erwähnen dies nicht in der Dokumentation, in How to use Abschnitt sie lokale Variable verwenden
Amit Battan
11

Wenn die Funktion beendet wird, gibt es keinen anderen Verweis auf den Popover-Controller, sodass die Zuordnung zu früh aufgehoben wird.

Versuchen Sie stattdessen, es als Mitglied Ihrer Klasse hinzuzufügen.

Tim

Tarmes
quelle
Sollte ich es nicht immer noch zuerst sehen können, bevor es freigegeben wird?
Mikayil Abdullayev
10

Wenn Sie hinzufügen, was @ phix23 beantwortet hat, erstellen Sie die * poc-Eigenschaft wie folgt:

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

und dann ändern

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

zum

self.poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];
orafaelreis
quelle
11
Sie müssen es nicht in Ihre .h-Datei einfügen. Das würde es öffentlich machen und wenn Sie das nicht wollen, machen Sie es einfach zu einer Eigenschaft in Ihrer .m-Datei.
Joshua Dance