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

NSClassFromStringyrespondsToSelectorentre 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 usorespondsToSelectoren 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 delNSObjectprotocolo.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 = yestructura es desenvolver valores opcionales (similares a!). Dado que está recibiendo unaBoolcopia de seguridadrespondsToSelector, el compilador se queja de que el resultado no es un tipo opcional (Bool?).vars declarado? ¿Todavía responden de la misma manera? En Objective-C podría hacerif ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }por unasomeVarpropiedad. ¿Funciona de la misma manera convars en Swift?No hay un reemplazo real de Swift.
Puede verificar de la siguiente manera:
Esto llama al método
someMethodsolo si está definido en un objeto,someObjectpero puede usarlo solo para@objcprotocolos 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 deNSObjectinstancias: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
guardes 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á, loVoidcual no es asínilobjecttiene 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
respondsToSelectorenfoque 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