Dengan ARC, saya tidak bisa lagi dilemparkan CGColorRef
ke id
. Saya belajar bahwa saya perlu melakukan pemeran penghubung. Menurut dentang dokumen :
Pemain yang dijembatani adalah pemain gaya-C yang diberi anotasi dengan salah satu dari tiga kata kunci:
(__bridge T) op
melemparkan operan ke tipe tujuanT
. JikaT
adalah tipe pointer objek yang dapat dipertahankan, makaop
harus memiliki tipe pointer yang tidak dapat dipertahankan. JikaT
adalah tipe pointer yang tidak dapat dipertahankan, maka op harus memiliki tipe pointer objek yang dapat dipertahankan. Kalau gips tidak terbentuk dengan baik. Tidak ada transfer kepemilikan, dan ARC memasukkan tidak ada operasi penahanan.
(__bridge_retained T) op
melemparkan operan, yang harus memiliki jenis penunjuk objek yang dapat dipertahankan, ke jenis tujuan, yang harus merupakan jenis penunjuk yang tidak dapat dipertahankan. ARC mempertahankan nilainya, tunduk pada optimasi yang biasa dilakukan pada nilai-nilai lokal, dan penerima bertanggung jawab untuk menyeimbangkan +1 tersebut.
(__bridge_transfer T) op
melemparkan operan, yang harus memiliki jenis penunjuk yang tidak dapat dipertahankan, ke jenis tujuan, yang harus merupakan jenis penunjuk objek yang dapat dipertahankan. ARC akan merilis nilai pada akhir ekspresi penuh terlampir, tunduk pada optimasi biasa pada nilai-nilai lokal.Gips ini diperlukan untuk mentransfer objek masuk dan keluar dari kontrol ARC; lihat alasan di bagian tentang konversi pointer objek yang dapat dipertahankan.
Menggunakan
__bridge_retained
atau__bridge_transfer
melemparkan murni untuk meyakinkan ARC untuk memancarkan masing-masing mempertahankan atau melepaskan tidak seimbang, adalah bentuk yang buruk.
Dalam situasi apa saya akan menggunakan masing-masing?
Misalnya, CAGradientLayer
memiliki colors
properti yang menerima array CGColorRef
s. Dugaan saya adalah bahwa saya harus menggunakan di __brige
sini, tetapi mengapa saya harus (atau tidak seharusnya) tidak jelas.
sumber
Jawaban:
Saya setuju bahwa uraiannya membingungkan. Karena saya baru saja memahami mereka, saya akan mencoba merangkum:
(__bridge_transfer <NSType>) op
atau sebagai alternatifCFBridgingRelease(op)
digunakan untuk mengkonsumsi retain-countCFTypeRef
sementara mentransfernya ke ARC. Ini juga bisa diwakili olehid someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
atau sebagai alternatifCFBridgingRetain(op)
digunakan untuk menyerahkan lahanNSObject
CF sambil memberikan penghitungan +1. Anda harus menanganiCFTypeRef
Anda membuat cara ini sama seperti Anda akan menangani hasilnyaCFStringCreateCopy()
. Ini juga bisa diwakili olehCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
hanya melemparkan antara pointer-land dan Objective-C objek-land. Jika Anda tidak memiliki kecenderungan untuk menggunakan konversi di atas, gunakan yang ini.Mungkin ini bermanfaat. Saya sendiri, saya lebih suka
CFBridging…
makro daripada gips.sumber
Saya menemukan penjelasan lain dalam dokumentasi iOS yang menurut saya lebih mudah dimengerti:
__bridge
mentransfer pointer antara Objective-C dan Core Foundation tanpa transfer kepemilikan.__bridge_retained (CFBridgingRetain)
melemparkan pointer Objective-C ke pointer Yayasan Core dan juga mentransfer kepemilikan kepada Anda.Anda bertanggung jawab untuk memanggil CFRelease atau fungsi terkait untuk melepaskan kepemilikan objek.
__bridge_transfer (CFBridgingRelease)
memindahkan pointer non-Objective-C ke Objective-C dan juga mentransfer kepemilikan ke ARC.ARC bertanggung jawab untuk melepaskan kepemilikan objek.
Sumber: Jenis Bridged Bebas Pulsa
sumber
Sebagai tindak lanjut, dalam kasus khusus ini, jika Anda menggunakan iOS, Apple merekomendasikan untuk menggunakan UIColor dan
-CGColor
metodenya untuk mengembalikan CGColorRef ke dalamcolors
NSArray. Dalam Transitioning to ARC Release Notes , di bawah bagian "The Compiler Menangani Objek CF yang Dikembalikan Dari Metode Kakao", diindikasikan bahwa menggunakan metode seperti-CGColor
yang mengembalikan objek Core Foundation akan secara otomatis ditangani dengan baik oleh kompiler.Dengan demikian, mereka menyarankan menggunakan kode seperti berikut:
Perhatikan bahwa pada saat ini, kode contoh Apple tidak memiliki tanda (id) yang saya miliki di atas, yang masih perlu untuk menghindari kesalahan kompiler.
sumber