Saya sudah mencari di Google tetapi tidak dapat menemukan apa yang setara dengan swift respondsToSelector:
.
Ini adalah satu-satunya hal yang dapat saya temukan ( alternatif Swift untuk respondToSelector:) tetapi tidak terlalu relevan dalam kasus saya karena memeriksa keberadaan delegasi, saya tidak memiliki delegasi yang saya hanya ingin memeriksa apakah ada API baru atau tidak ketika berjalan di perangkat dan jika tidak kembali ke versi api sebelumnya.
objective-c
swift
selector
Gruntcakes
sumber
sumber
NSClassFromString
dan direspondsToSelector
antara mekanisme lainnya untuk memeriksa fungsionalitas yang baru diimplementasikan, saya harus percaya bahwa mekanisme sudah ada di tempat, atau akan ada sebelum rilis. Coba tontonAdvanced Interop...
videonya dari WWDC.if #available(...)
Swift 2.x untuk menghindari penggunaanrespondsToSelector
di tempat pertama. Tapi kamu tahu itu. ( apple.co/1SNGtMQ )Jawaban:
Seperti yang disebutkan, di Swift sebagian besar waktu Anda dapat mencapai apa yang Anda butuhkan dengan
?
operator pembuka bungkus opsional . Ini memungkinkan Anda untuk memanggil metode pada objek jika dan hanya jika objek itu ada (tidaknil
) dan metode tersebut diterapkan.Dalam kasus di mana Anda masih perlu
respondsToSelector:
, itu masih ada sebagai bagian dariNSObject
protokol.Jika Anda memanggil
respondsToSelector:
tipe Obj-C di Swift, maka itu berfungsi sama seperti yang Anda harapkan. Jika Anda menggunakannya di kelas Swift Anda sendiri, Anda harus memastikan kelas Anda berasalNSObject
.Berikut adalah contoh dari kelas Swift yang dapat Anda periksa jika merespons pemilih:
Penting agar Anda tidak mengabaikan nama parameter. Dalam contoh ini,
Selector("sleep::")
adalah tidak sama denganSelector("sleep:minutes:")
.sumber
let x =
bagiannya. Pada dasarnya,if let x = y
struktur adalah untuk membuka nilai opsional (mirip dengan!
). Karena Anda mendapatkanBool
kembali darirespondsToSelector
, kompiler mengeluh bahwa hasilnya bukan tipe opsional (Bool?
).var
yang dinyatakan? Apakah mereka masih menanggapi dengan cara yang sama? Di Objective-C saya bisa lakukanif ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }
untuksomeVar
properti. Apakah itu bekerja dengan cara yang sama denganvar
s di Swift?Tidak ada pengganti Swift nyata.
Anda dapat memeriksa dengan cara berikut:
Ini memanggil metode
someMethod
hanya jika itu didefinisikan pada objeksomeObject
tetapi Anda dapat menggunakannya hanya untuk@objc
protokol yang menyatakan metode sebagaioptional
.Swift secara inheren adalah bahasa yang aman sehingga setiap kali Anda memanggil metode, Swift harus tahu metode itu ada di sana. Tidak ada pemeriksaan runtime yang memungkinkan. Anda tidak bisa hanya memanggil metode acak pada objek acak.
Bahkan di Obj-C Anda harus menghindari hal-hal seperti itu jika memungkinkan karena tidak cocok dengan ARC (ARC kemudian memicu peringatan untuk
performSelector:
).Namun, saat memeriksa API yang tersedia, Anda masih dapat menggunakan
respondsToSelector:
, bahkan jika Swift, jika Anda berurusan denganNSObject
instance:sumber
respondsToSelector:
karena rekomendasi Apple secara eksplisit bahwa Anda harus melakukannya. Lihat di sinirespondsToSelector:
yang sebenarnya bagus untuk dimiliki. Tetapi jika Anda membaca referensi Swift, mereka berbicara tentang menggunakan subclass untuk versi sistem yang berbeda.if #available(iOS 10) {
dan kemudian memanggil metode secara langsung.Pembaruan 20 Mar 2017 untuk sintaks Swift 3:
Jika Anda tidak peduli apakah ada metode opsional, panggil saja
delegate?.optionalMethod?()
Kalau tidak, menggunakan
guard
mungkin merupakan pendekatan terbaik:Jawaban asli:
Anda dapat menggunakan pendekatan "jika dibiarkan" untuk menguji protokol opsional seperti ini:
sumber
let theMethod = delegate.userNotificationCenter(_:willPresent:withCompletionHandler:)
Tampaknya Anda perlu mendefinisikan protokol Anda sebagai subprotocol dari NSObjectProtocol ... maka Anda akan mendapatkan metode respondsToSelector
perhatikan bahwa hanya menetapkan @objc tidak cukup. Anda juga harus berhati-hati bahwa delegasi yang sebenarnya adalah subkelas dari NSObject - yang mungkin tidak ada di Swift.
sumber
Jika metode yang Anda uji didefinisikan sebagai metode opsional dalam protokol @objc (yang terdengar seperti kasus Anda), maka gunakan pola rangkaian opsional sebagai:
Ketika metode ini dinyatakan sebagai kembali
Void
, cukup gunakan:Lihat:
sumber
if object.method?(args) { ... }
- panggilan metode, bila ada, akan kembaliVoid
yang tidaknil
object
memiliki tipeAnyObject
, Anda dapat menguji metode @objc apa pun.Fungsi adalah tipe kelas satu di Swift, jadi Anda dapat memeriksa apakah fungsi opsional yang didefinisikan dalam protokol telah diterapkan dengan membandingkannya dengan nihil:
sumber
Untuk swift3
Jika Anda hanya ingin memanggil metode, jalankan kode di bawah ini.
self.delegate?.method?()
sumber
Di Swift 2, Apple memperkenalkan fitur baru yang disebut
API availability checking
, yang mungkin menjadi pengganti metoderespondsToSelector:
. Perbandingan cuplikan kode berikut disalin dari WWDC2015 Sesi 106 Apa yang Baru di Swift yang saya pikir mungkin dapat membantu Anda, silakan periksa jika Anda perlu tahu lebih banyak.sumber
respondsToSelector
pendekatan di Swift. Itu juga karena pemeriksaan pemilih bukan solusi terbaik untuk masalah ini (pengecekan ketersediaan) sejak awal.Untuk swift 3.0
sumber
Saat ini (Swift 2.1) Anda dapat memeriksanya menggunakan 3 cara:
Menggunakan '?' dijawab oleh @Sulthan
Dan menggunakan
as?
operator:Pada dasarnya itu tergantung pada apa yang ingin Anda capai:
sumber
Saya hanya mengimplementasikan ini sendiri dalam sebuah proyek, lihat kode di bawah ini. Seperti yang disebutkan oleh @Christopher Pickslay, penting untuk diingat bahwa fungsi adalah warga negara kelas satu dan karenanya dapat diperlakukan seperti variabel opsional.
sumber
sintaks lain yang mungkin oleh swift ..
sumber
Ketika saya mulai memperbarui proyek lama saya ke Swift 3.2, saya hanya perlu mengubah metode dari
untuk:
sumber
Saya menggunakan
guard let else
, sehingga dapat melakukan beberapa hal standar jika fungsi delegasi tidak diimplementasikan.sumber
Swift 3:
protokol
Obyek
sumber
Setara dengan itu? operator:
importantMethod hanya akan dipanggil jika myQuestionableObject ada dan mengimplementasikannya.
sumber
?
afterimportantMethod