Di Swift, saya melihat beberapa metode seperti:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
Saya bertanya-tanya, kapan harus menggunakan @objc? Saya membaca beberapa dokumen, tetapi mereka mengatakan ketika Anda ingin itu dapat dipanggil di Objective-C, Anda harus menambahkan bendera @objc
Namun, ini adalah fungsi pribadi di Swift, apa yang dilakukan @obj?
Jawaban:
private berarti hanya terlihat di Swift. jadi gunakan @objc agar terlihat di Objective-C. Jika Anda memiliki func to selector, sebuah fungsi privat dengan cepat, itu diperlukan.
Lihat: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
sumber
@objc private func doubleTapGestureRecognized
, apa gunanya memiliki @objc dan pribadi? Apakah Anda mengatakan kelas Objective-C bisa menimpa doubleTapGestureRecognized?Jawaban terlambat lainnya, tetapi tidak ada jawaban yang ada pada pertanyaan ini yang benar-benar menjawab pertanyaan OP, yaitu: mengapa sih yang perlu Anda gunakan
@objc
pada anggotaprivate
kelas, jika@objc
ada untuk interaksi dengan Objective-C, dan anggota yang bersangkutan bersifat pribadi, artinya meskipun Anda memiliki kode Objective-C dalam proyek Anda, ia seharusnya tidak dapat melihat anggotanya?Alasannya adalah, karena banyak framework yang ditulis di Objective-C, terkadang fitur Objective-C diperlukan untuk berinteraksi dengan API tertentu.
Misalnya, saya ingin mendaftar notifikasi melalui
DistributedNotificationCenter
:DistributedNotificationCenter.default.addObserver(self, selector: #selector(somethingHappened(_:)), name: someNotification, object: nil)
Agar ini berfungsi, kita harus bisa mendapatkan pemilih untuk
somethingHappened
metode tersebut. Namun, penyeleksi adalah konsep Objective-C, jadi jika metode tidak terlihat oleh Objective-C, itu tidak memiliki selector. Oleh karena itu, meskipun metode tersebut bersifat pribadi dan tidak boleh dipanggil oleh kode luar arbitrer, ia memerlukan@objc
agarDistributedNotification
kode, yang ditulis dalam Objective-C, dapat memanggilnya melalui selektornya.Kasus umum lainnya
@objc
yang diperlukan adalah untuk mendukung Key-Value Coding (KVC), terutama di macOS, di mana KVC dan KVO digunakan untuk mengimplementasikan Cocoa Bindings. KVC, seperti banyak sistem lain di Cocoa, diimplementasikan di Objective-C, yang memiliki efek mengharuskan properti yang sesuai dengan KVC diekspos ke runtime Objective-C. Terkadang, masuk akal jika properti yang sesuai dengan KVC bersifat pribadi. Salah satu contohnya adalah ketika Anda memiliki properti yang memengaruhi properti lain:@objc private dynamic var originalProperty: String @objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [ #keyPath(originalProperty) ] @objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
Dalam hal ini, milik kita yang sebenarnya disimpan pribadi, tetapi milik tergantung, yang kita lakukan mengekspos kode luar, perlu mengirim pemberitahuan ketika properti pribadi diperbarui. Dengan menandai properti pribadi sebagai
@objc
, kita dapat dengan mudah melakukannya dengan menyiapkan ketergantungan KVC — jika tidak, kita harus menulis kode untuk mengirim pemberitahuan secara manual di propertiwillSet
dandidSet
penangan pribadi. Selain itu, properti statis yang menginformasikan sistem KVC yangdependentProperty
bergantung padaoriginalProperty
perlu diekspos ke Objective-C sehingga sistem KVC menemukan dan memanggilnya, tetapi itu tidak relevan untuk klien kode kami.Selain itu, pengontrol tampilan di app macOS yang memperbarui kontrol dalam tampilannya menggunakan Cocoa Bindings sebagai detail implementasi dapat membuat properti pribadi tertentu sesuai dengan KVC untuk mengikat kontrol tersebut ke properti tersebut.
Jadi seperti yang Anda lihat, ada kalanya metode atau properti perlu diekspos ke Objective-C untuk berinteraksi dengan kerangka kerja, tanpa harus terlihat oleh klien kode Anda.
sumber
@objc / dinamis
Ini untuk kompatibilitas: Setelah Anda mengimpor file / kode Swift Anda ke dalam proyek berbasis Objective-C.
Dan gunakan itu jika Anda ingin properti / metode Anda diakses oleh kode atau kelas Objective-C.
Sebagian besar waktu itu terjadi ketika Anda mengelompokkan kelas Swift dari kelas dasar Objective-C.
Berikut dokumentasi apel yang mengatakan tentang
@objc
.Menggunakan Swift dari Objective-C
Kompatibilitas Interoperabilitas Bahasa
Tautan Diperbarui:
Sepertinya tautan telah diperbarui oleh apple.
sumber
@objc adalah atribut kelas, jadi Anda menggunakan
@objc public class MyClass
Ini mengekspos metode kelas ke kelas Objective C, jadi Anda hanya akan menggunakannya jika kelas Anda berisi fungsi publik
sumber
Jawaban terlambat, tetapi
@objc
perilaku ini sedikit berubah pada Swift 4 (yang keluar di Xcode 9, yang umumnya dirilis 10 hari yang lalu).Di Swift 4, beberapa kasus inferensi
@objc
dihapus. Ini hanya berarti dalam beberapa kasus tambahan di mana sebelum@objc
header disimpulkan oleh kompiler Swift, di Swift 4 tidak disimpulkan.Baca lebih lanjut di proposal evolusi Swift tentang perubahan ini
Seperti yang telah disebutkan, secara umum
@objc
adalah mengekspos metode tertentu ke runtime Objective-C, yang merupakan bagian dari interoperabilitas Swift bahasa.sumber
@objc
@objc
mengekspos deklarasi keObjective-C runtime
. Mari kita lihat#selector
fitur Swift untuk menggunakan runtime Objective-C. Dalam hal ini Anda dapat menentukan Swift Anda@objc private func
[Lainnya]Untuk menggunakan fungsi Swift dari Objective-C:
NSObject
Mark Swift:
Sebuah. hanya
@objcMembers
kelas - untuk mengekspos semuapublic
konstruktor , bidang , dan metode . Juga berlaku untuk subclassb.
@objc
class / enum / protocol (kecuali struct ) [Named Type]@objc
class (opsional) - untuk menampilkan defaultpublic init()
. Atau@objc(<custom_name>)
untuk menyiapkan nama khusus untuk kelas.@objc
konstruktor , bidang dan metode - untuk mengeksposnya secara selektifMetode Swift akan tersedia dengan penamaan berikutnya:
<swiftName>With<firstArgument>:<secondArgument>:
Sebagai contoh:
public func printHelloWorld(arg1: String, arg2:String) //is reached through: [someObject printHelloWorldWithArg1: arg2:];
[
@objc
dandynamic
]sumber