Dealloc UIPopovercontroller tercapai saat popover masih terlihat

111

Saya yakinkan Anda bahwa saya memang mencari jawaban di SO untuk pertanyaan saya tetapi tidak ada yang membantu. Di sini saya mendapat kode sederhana yang harus ada di UIImagePickerControllerdalam 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];
}

Sekarang, bahkan dari pertama kali saya [UIPopoveController dealloc]dihubungi saat ... kesalahan dan program macet. Saya tidak melakukan retensi, relase, atau autoreleases apa pun sesuai ARC. Apakah ada pertimbangan khusus UIPopoverControllerssaat mendapatkan manfaat dari ARC?

Mikayil Abdullayev
sumber

Jawaban:

203

UIPopoverControllers harus selalu disimpan dalam variabel instance. Ini adalah praktik yang baik untuk menciptakan properti yang kuat untuknya.

MEMPERBARUI:

Mulai iOS 8, Anda harus menggunakan UIPopoverPresentationController. Maka Anda tidak perlu menyimpan referensi ke popover karena dikelola oleh pengontrol presentasi.

Contoh kode (berfungsi baik di iPhone dan 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
sumber
1
Oh begitu. Tapi bukankah ini seperti UIAlertView? Saya tidak pernah memiliki ivar untuk itu, saya hanya mengalokasikannya di mana pun saya butuhkan, menunjukkannya dan kemudian [dulu] melepaskannya. Dalam hal apa popovercontroller berbeda?
Mikayil Abdullayev
17
@Mikayil AlertView dipertahankan oleh superview-nya (seperti semua tampilan), tetapi popoverController bukanlah tampilan, jadi tidak memiliki superview, jadi tidak akan disimpan oleh siapa pun jika Anda tidak menyimpannya (atau simpan dalam variabel kuat yang memiliki cakupan yang lebih panjang dari metode saat ini - misalnya iVar).
fzwo
1
Tapi saya masih bingung tentang jumlah retensi UIPopoverController. Karena saya memberi tanda centang sebelum saya mengalokasikan dan memasukkannya. Dan hanya jika tidak ada saya mengalokasikan yang baru. Tapi setelah mengalokasikannya untuk pertama kali saya tidak pernah mendapatkannya nihil. Maksud saya, saya menyebut metode sekali. Di sana saya mengalokasikan dan menginit ivar saya. Dan lain kali ketika saya memanggil metode itu lagi kali ini saya menemukan ivar saya sudah dialokasikan. Jika ARC menangani ini, lalu kapan merilisnya. Atau apakah itu melepaskannya secara otomatis?
Mikayil Abdullayev
Ivars @Mikayil dilepaskan oleh ARC saat objek dibatalkan alokasinya atau saat Anda menyetelnya ke nihil
Felix
tetapi mereka tidak menyebutkan ini dalam dokumentasi, di bagian Cara Menggunakan mereka menggunakan variabel lokal
Amit Battan
11

Saat fungsi keluar, tidak ada referensi lain ke pengontrol popover, jadi alokasinya terlalu dini.

Coba tambahkan sebagai anggota kelas Anda sebagai gantinya.

Tim

Aspal
sumber
Bukankah seharusnya saya masih dapat melihatnya terlebih dahulu sebelum dialokasikan?
Mikayil Abdullayev
10

Menambahkan apa yang dijawab @ phix23, buat properti * poc seperti ini:

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

dan kemudian berubah

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

untuk

self.poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];
orafaelreis
sumber
11
Anda tidak harus memasukkannya ke dalam file .h Anda. Itu akan membuatnya menjadi publik dan kecuali Anda menginginkannya, jadikan saja properti di file .m Anda.
Joshua Dance