Saya mengembangkan secara eksklusif untuk iOS 5 menggunakan ARC. Haruskah IBOutlet
s ke UIView
s (dan subclass) menjadi strong
atau weak
?
Pengikut:
@property (nonatomic, weak) IBOutlet UIButton *button;
Akan menyingkirkan semua ini:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Apakah ada masalah dalam melakukan ini? Templat menggunakan strong
seperti halnya properti yang dibuat secara otomatis dibuat ketika menghubungkan langsung ke header dari editor 'Pembuat Antarmuka', tetapi mengapa? Yang UIViewController
sudah memiliki strong
referensi untuk view
yang mempertahankan subview.
IBOutletCollection()
tidak bolehweak
, jika tidak kembali sebagainil
.strong
Jawaban:
Praktik terbaik yang direkomendasikan saat ini dari Apple adalah agar IBOutlets menjadi kuat kecuali jika lemah diperlukan secara khusus untuk menghindari siklus penyimpanan. Seperti yang disebutkan oleh Johannes di atas, ini dikomentari dalam sesi "Menerapkan Desain UI dalam Interface Builder" dari WWDC 2015 di mana seorang Insinyur Apple berkata:
Saya bertanya tentang ini di Twitter kepada seorang insinyur di tim IB dan dia mengkonfirmasi bahwa kuat harus menjadi default dan bahwa dokumen pengembang sedang diperbarui.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
sumber
PERINGATAN, JAWABAN KEDUA : jawaban ini tidak mutakhir sesuai WWDC 2015, untuk jawaban yang benar mengacu pada jawaban yang diterima (Daniel Hall) di atas. Jawaban ini akan tetap dicatat.
Dirangkum dari perpustakaan pengembang :
sumber
Meskipun dokumentasi merekomendasikan penggunaan
weak
pada properti untuk subview, karena iOS 6 tampaknya baik-baik saja untuk digunakanstrong
(kualifikasi kepemilikan default) sebagai gantinya. Itu disebabkan oleh perubahan dalamUIViewController
pandangan yang tidak diturunkan lagi.Yang mengatakan, saya terpecah antara menggunakan
dan
di iOS 6 dan setelah:
Dengan
weak
jelas menyatakan bahwa pengontrol tidak menginginkan kepemilikan tombol.Tetapi menghilangkan
weak
tidak ada salahnya di iOS 6 tanpa tampilan bongkar, dan lebih pendek. Beberapa mungkin menunjukkan itu juga lebih cepat, tetapi saya belum menemukan aplikasi yang terlalu lambat karenaweak
IBOutlet
s.Tidak menggunakan
weak
dapat dianggap sebagai kesalahan.Intinya: Sejak iOS 6 kita tidak bisa mendapatkan kesalahan ini lagi selama kita tidak menggunakan view unloading. Waktunya berpesta. ;)
sumber
nil
secara manual.weak
sedikit lebih murah di ARM64: Dweak
properti atau__weak
variabel instan adalah cara untuk pergi. Saya hanya ingin menunjukkan bahwa ada sedikit potensi kesalahan di sini. Adapunweak
menjadi lebih murah di arm64, saya bahkan belum melihat masalah kinerja kehidupan nyata denganweak
IBOutlet
s pada armv7. :)strong
masuk akal juga.strong
hanya berbahaya jika Anda menggunakan view unloading — tetapi siapa yang melakukannya hari ini? :)Saya tidak melihat masalah dengan itu. Pra-ARC, saya selalu membuat IBOutlet saya
assign
, karena mereka sudah dipertahankan oleh superview mereka. Jika Anda membuatnyaweak
, Anda tidak harus menghilangkannya di viewDidUnload, seperti yang Anda tunjukkan.Satu peringatan: Anda dapat mendukung iOS 4.x dalam proyek ARC, tetapi jika Anda melakukannya, Anda tidak dapat menggunakan
weak
, jadi Anda harus membuatnyaassign
, dalam hal ini Anda masih ingin memasukkan referensiviewDidUnload
untuk menghindari pointer menggantung. Berikut adalah contoh bug penunjuk menggantung yang saya alami:UIViewController memiliki UITextField untuk kode pos. Ini menggunakan CLLocationManager untuk membalikkan geocode lokasi pengguna dan mengatur kode pos. Inilah panggilan balik delegasi:
Saya menemukan bahwa jika saya menolak pandangan ini pada waktu yang tepat dan tidak nihil. Zip masuk
viewDidUnload
, panggilan balik delegasi dapat membuang pengecualian akses buruk pada self.zip.text.sumber
weak
properti tidak perlu diisiviewDidUnload
. Tetapi mengapa template Apple untuk membuat outlet mencakup[self setMySubview:nil]
?IBOutlet
harus kuat, karena alasan kinerja. Lihat Referensi Storyboard, IBOutlet Kuat, Adegan Dok di iOS 9Pada Xcode 7, disarankan
strong
Jika Anda menonton WWDC 2015 sesi 407 Menerapkan Desain UI di Interface Builder , itu menyarankan (transkrip dari http://asciiwwdc.com/2015/sessions/407 )
sumber
Dalam pengembangan iOS, pemuatan NIB sedikit berbeda dari pengembangan Mac.
Dalam pengembangan Mac, IBOutlet biasanya merupakan referensi yang lemah: jika Anda memiliki subkelas NSViewController, hanya tampilan tingkat atas yang akan dipertahankan dan ketika Anda membatalkan pengontrol semua subview dan outletnya dibebaskan secara otomatis.
UiViewController menggunakan Key Value Coding untuk mengatur outlet menggunakan referensi yang kuat. Jadi ketika Anda membatalkan alokasi UIViewController Anda, tampilan teratas akan secara otomatis dialokasikan, tetapi Anda juga harus membatalkan alokasi semua outletnya dalam metode dealloc.
Dalam posting ini dari Peternakan Big Nerd , mereka membahas topik ini dan juga menjelaskan mengapa menggunakan referensi yang kuat di IBOutlet bukanlah pilihan yang baik (bahkan jika direkomendasikan oleh Apple dalam kasus ini).
sumber
Satu hal yang ingin saya tunjukkan di sini, dan itu adalah, terlepas dari apa yang para insinyur Apple nyatakan dalam video WWDC 2015 mereka di sini:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple terus mengubah pikiran mereka tentang masalah ini, yang memberi tahu kita bahwa tidak ada jawaban yang benar untuk pertanyaan ini. Untuk menunjukkan bahwa bahkan insinyur Apple terpecah mengenai hal ini, lihat kode sampel terbaru Apple, dan Anda akan melihat beberapa orang menggunakan yang lemah, dan beberapa tidak.
Contoh Apple Pay ini menggunakan lemah: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_Wift
Seperti halnya contoh gambar-dalam-gambar ini: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPlayer_Pelanggan_Pelatihan_PemainKebijakan_Pelajaran_Pemain
Seperti halnya contoh Lister: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Seperti halnya contoh Lokasi Inti: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_Potloc_Potloc_Potloc_Delokkan_ID
Seperti halnya contoh pratinjau pengontrol tampilan: https://developer.apple.com/library/ios/samplecode/viewControllerPelajar/daftar/Tumbuh/Tumbi
Seperti halnya contoh HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP4camp_cetak_dorongAnda_Karena_MemilikiKelasKaca_Memiliki
Semua itu sepenuhnya diperbarui untuk iOS 9, dan semua menggunakan outlet yang lemah. Dari sini kita belajar bahwa A. Masalahnya tidak sesederhana beberapa orang mengetahuinya. B. Apple telah berubah pikiran berulang kali, dan C. Anda dapat menggunakan apa pun yang membuat Anda bahagia :)
Terima kasih khusus kepada Paul Hudson (penulis www.hackingwithsift.com) yang memberi saya klarifikasi, dan referensi untuk jawaban ini.
Saya harap ini memperjelas masalah ini sedikit lebih baik!
Hati hati.
sumber
Dari WWDC 2015 ada sesi tentang Menerapkan Desain UI di Interface Builder . Sekitar tanda 32 menit ia mengatakan bahwa Anda selalu ingin membuat Anda
@IBOutlet
kuat .sumber
Waspada,
IBOutletCollection
seharusnya@property (strong, nonatomic)
.sumber
copy
seperti ituNSArray
?Sepertinya ada sesuatu yang berubah selama bertahun-tahun dan sekarang Apple merekomendasikan untuk menggunakan yang kuat secara umum. Bukti pada sesi WWDC mereka ada di sesi 407 - Menerapkan Desain UI di Interface Builder dan mulai pukul 32:30. Catatan saya dari apa yang dia katakan adalah (hampir, jika tidak tepat, mengutipnya):
koneksi outlet secara umum harus kuat terutama jika kita menghubungkan subview atau kendala yang tidak selalu dipertahankan oleh hierarki tampilan
koneksi outlet yang lemah mungkin diperlukan saat membuat tampilan khusus yang memiliki referensi untuk sesuatu yang dicadangkan dalam hierarki tampilan dan secara umum tidak disarankan
Di bangsal lain itu harus selalu kuat sekarang selama beberapa tampilan kustom kami tidak membuat siklus mempertahankan dengan beberapa tampilan di hierarki tampilan
EDIT:
Beberapa mungkin mengajukan pertanyaan. Apakah menjaganya dengan referensi yang kuat tidak membuat siklus penahan karena pengontrol tampilan root dan tampilan memiliki menyimpan referensi untuk itu? Atau mengapa perubahan itu terjadi? Saya pikir jawabannya di awal pembicaraan ini ketika mereka menggambarkan bagaimana biji dibuat dari xib. Ada pena terpisah yang dibuat untuk VC dan untuk tampilan. Saya pikir ini mungkin alasan mengapa mereka mengubah rekomendasi. Tetap menyenangkan untuk mendapatkan penjelasan yang lebih dalam dari Apple.
sumber
Saya pikir informasi yang paling penting adalah: Elemen-elemen di xib secara otomatis dalam tampilan subview. Subview adalah NSArray. NSArray memiliki elemen-elemennya. dll punya petunjuk kuat pada mereka. Jadi dalam kebanyakan kasus Anda tidak ingin membuat pointer kuat lain (IBOutlet)
Dan dengan ARC Anda tidak perlu melakukan apa-apa
viewDidUnload
sumber