He buscado en Google pero no he podido averiguar cuál es el equivalente rápido de respondsToSelector:
.
Esto es lo único que pude encontrar ( alternativa rápida a respondsToSelector:) pero no es demasiado relevante en mi caso, ya que verifica la existencia del delegado, no tengo un delegado, solo quiero verificar si existe una nueva API o no cuando se ejecuta en el dispositivo y, si no, recurrir a una versión anterior de la API.
objective-c
swift
selector
Tortas Grunt
fuente
fuente
NSClassFromString
yrespondsToSelector
entre otras mecánicas para verificar la funcionalidad recientemente implementada, tengo que creer que los mecanismos ya están implementados o estarán allí antes del lanzamiento. Intenta ver elAdvanced Interop...
video de WWDC.if #available(...)
Swift 2.x para evitar el usorespondsToSelector
en primer lugar. Pero eso ya lo sabías. ( apple.co/1SNGtMQ )Respuestas:
Como se mencionó, en Swift la mayoría de las veces puede lograr lo que necesita con el
?
operador de desenvoltura opcional . Esto le permite llamar a un método en un objeto si y solo si el objeto existe (nonil
) y el método está implementado.En el caso en que aún lo necesite
respondsToSelector:
, todavía está allí como parte delNSObject
protocolo.Si está llamando
respondsToSelector:
a un tipo Obj-C en Swift, entonces funciona igual de lo esperado. Si lo está utilizando en su propia clase Swift, deberá asegurarse de que su clase se deriveNSObject
.Aquí hay un ejemplo de una clase Swift que puede verificar si responde a un selector:
Es importante que no omita los nombres de los parámetros. En este ejemplo, no
Selector("sleep::")
es lo mismo queSelector("sleep:minutes:")
.fuente
let x =
parte. Básicamente, laif let x = y
estructura es desenvolver valores opcionales (similares a!
). Dado que está recibiendo unaBool
copia de seguridadrespondsToSelector
, el compilador se queja de que el resultado no es un tipo opcional (Bool?
).var
s declarado? ¿Todavía responden de la misma manera? En Objective-C podría hacerif ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }
por unasomeVar
propiedad. ¿Funciona de la misma manera convar
s en Swift?No hay un reemplazo real de Swift.
Puede verificar de la siguiente manera:
Esto llama al método
someMethod
solo si está definido en un objeto,someObject
pero puede usarlo solo para@objc
protocolos que han declarado el método comooptional
.Swift es un lenguaje inherentemente seguro, por lo que cada vez que llama a un método Swift tiene que saber que el método está allí. No es posible verificar el tiempo de ejecución. No puede simplemente llamar a métodos aleatorios en objetos aleatorios.
Incluso en Obj-C debe evitar tales cosas cuando sea posible porque no funciona bien con ARC (ARC luego activa advertencias para
performSelector:
).Sin embargo, al verificar las API disponibles, aún puede usar
respondsToSelector:
, incluso si Swift, si se trata deNSObject
instancias:fuente
respondsToSelector:
ya que la recomendación de Apple es explícitamente que debes hacerlo. Ver aquírespondsToSelector:
es realmente bueno tenerlo. Pero si revisa la referencia de Swift, hablan sobre el uso de subclases para diferentes versiones del sistema.if #available(iOS 10) {
y luego llamamos al método directamente.Actualización del 20 de marzo de 2017 para la sintaxis de Swift 3:
Si no le importa si existe el método opcional, simplemente llame
delegate?.optionalMethod?()
De lo contrario, usar
guard
es probablemente el mejor enfoque:Respuesta original:
Puede usar el enfoque "if let" para probar un protocolo opcional como este:
fuente
let theMethod = delegate.userNotificationCenter(_:willPresent:withCompletionHandler:)
Parece que necesita definir su protocolo como un subprotocolo de NSObjectProtocol ... entonces obtendrá el método respondsToSelector
tenga en cuenta que solo especificar @objc no fue suficiente. También debe tener cuidado de que el delegado real sea una subclase de NSObject, que en Swift podría no serlo.
fuente
Si el método que está probando se define como un método opcional en un protocolo @objc (que suena como su caso), entonces use el patrón de encadenamiento opcional como:
Cuando el método se declara como de retorno
Void
, simplemente use:Ver:
fuente
if object.method?(args) { ... }
, la llamada del método, cuando exista, regresará, loVoid
cual no es asínil
object
tiene tipoAnyObject
, puede probar cualquier método @objc.Las funciones son tipos de primera clase en Swift, por lo que puede verificar si se ha implementado una función opcional definida en un protocolo comparándola con nil:
fuente
Para swift3
Si solo desea llamar al método, ejecute el código a continuación.
self.delegate?.method?()
fuente
En Swift 2, Apple introdujo una nueva función llamada
API availability checking
, que podría ser un reemplazo para elrespondsToSelector:
método. La siguiente comparación de fragmentos de código se copia de la sesión 106 de WWDC2015 Novedades en Swift que pensé que podría ayudarlo, por favor, compruébelo si necesita saber más.fuente
respondsToSelector
enfoque en Swift. Eso también se debe a que la verificación del selector no fue la mejor solución para este problema (verificación de disponibilidad) en primer lugar.Para swift 3.0
fuente
Actualmente (Swift 2.1) puede verificarlo de 3 maneras:
Usando '?' respondido por @Sulthan
Y usando el
as?
operador:Básicamente depende de lo que intentes lograr:
fuente
Solo lo implemento yo mismo en un proyecto, vea el código a continuación. Como menciona @Christopher Pickslay, es importante recordar que las funciones son ciudadanos de primera clase y, por lo tanto, pueden tratarse como variables opcionales.
fuente
otra sintaxis posible por swift ..
fuente
Cuando comencé a actualizar mi antiguo proyecto a Swift 3.2, solo necesitaba cambiar el método de
a:
fuente
Yo uso
guard let else
, por lo que puede hacer algunas cosas predeterminadas si el delegado func no está implementado.fuente
Swift 3:
protocolo
Objeto
fuente
El equivalente es el? operador:
importantMethod solo se llamará si myQuestionableObject existe y lo implementa.
fuente
?
afterimportantMethod