suzuki sport precio boosterjet swift

swift - sport - ¿Cuál es el equivalente rápido de respondsToSelector?



swift sport (16)

Para swift3

Si solo desea llamar al método, ejecute el siguiente código.

self.delegate?.method?()

He buscado en Google pero no he podido averiguar cuál es el equivalente rápido de respondsToSelector: es.

Esto es lo único que pude encontrar ( alternativa de Swift 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 API nueva. o no cuando se ejecuta en el dispositivo y si no recurre a una versión anterior de la API.


Actualmente (Swift 2.1) puedes verificarlo usando 3 formas:

  1. Usando respondsToSelector respondido por @Erik_at_Digit
  2. Usando ''?'' respondido por @Sulthan

  3. Y usando as? operador:

    if let delegateMe = self.delegate as? YourCustomViewController { delegateMe.onSuccess() }

Básicamente depende de lo que estás tratando de lograr:

  • Si, por ejemplo, la lógica de su aplicación necesita realizar alguna acción y el delegado no está configurado o el delegado puntual no implementó el método onSuccess () (método de protocolo), entonces la opción 1 y 3 son la mejor opción, aunque usaría opción 3, que es Swift way.
  • Si no quiere hacer nada cuando el delegado es nulo o el método no está implementado, entonces use la opción 2.

Como se mencionó, en Swift la mayoría de las veces puede lograr lo que necesita con el ? operador desempaquetador opcional . Esto le permite llamar a un método en un objeto si y solo si el objeto existe (no es nil ) y el método se implementa.

En el caso de que todavía necesite respondsToSelector: todavía está allí como parte del protocolo NSObject .

Si está llamando a respondsToSelector: en un tipo Obj-C en Swift, entonces funciona igual que cabría esperar. Si lo está usando en su propia clase Swift, deberá asegurarse de que su clase se deriva de NSObject .

Aquí hay un ejemplo de una clase Swift que puede verificar si responde a un selector:

class Worker : NSObject { func work() { } func eat(food: AnyObject) { } func sleep(hours: Int, minutes: Int) { } } let worker = Worker() let canWork = worker.respondsToSelector(Selector("work")) // true let canEat = worker.respondsToSelector(Selector("eat:")) // true let canSleep = worker.respondsToSelector(Selector("sleep:minutes:")) // true let canQuit = worker.respondsToSelector(Selector("quit")) // false

Es importante que no omita los nombres de los parámetros. En este ejemplo, Selector("sleep::") no es lo mismo que Selector("sleep:minutes:") .


Cuando comencé a actualizar mi antiguo proyecto a Swift 3.2, solo necesitaba cambiar el método de

respondsToSelector(selector)

a:

responds(to: selector)


El equivalente es el? operador:

var value: NSNumber? = myQuestionableObject?.importantMethod()

importantMethod solo se invocará si myQuestionableObject existe y lo implementa.


En Swift 2, Apple introdujo una nueva característica llamada API availability checking , que podría ser un reemplazo para el método respondsToSelector: siguiente comparación de fragmentos de código se copia de la sesión de WWDC2015. 106 Novedades de Swift que pensé que podrían serle útiles, revíselo si necesitas saber más.

El viejo enfoque:

@IBOutlet var dropButton: NSButton! override func awakeFromNib() { if dropButton.respondsToSelector("setSpringLoaded:") { dropButton.springLoaded = true } }

El mejor enfoque:

@IBOutlet var dropButton: NSButton! override func awakeFromNib() { if #available(OSX 10.10.3, *) { dropButton.springLoaded = true } }


Las funciones son tipos de primera clase en Swift, por lo que puede verificar si una función opcional definida en un protocolo se ha implementado comparándola con nil:

if (someObject.someMethod != nil) { someObject.someMethod!(someArgument) } else { // do something else }


No hay un reemplazo real de Swift.

Puede verificar de la siguiente manera:

someObject.someMethod?()

Esto llama al método someMethod solo si está definido en el objeto someObject pero puede usarlo solo para los protocolos @objc que hayan declarado que el método es optional .

Swift es intrínsecamente un lenguaje seguro, por lo que cada vez que llamas a un método Swift tiene que saber que el método está ahí. No es posible verificar el tiempo de ejecución. No puedes simplemente llamar a métodos aleatorios en objetos aleatorios.

Incluso en Obj-C debe evitar tales cosas cuando sea posible, ya que 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 está tratando con instancias de NSObject :

@interface TestA : NSObject - (void)someMethod; @end @implementation TestA //this triggers a warning @end


var a = TestA() if a.respondsToSelector("someMethod") { a.someMethod() }


Parece que necesita definir su protocolo como subprotocolo de NSObjectProtocol ... luego obtendrá el método respondsToSelector

@objc protocol YourDelegate : NSObjectProtocol { func yourDelegateMethod(passObject: SomeObject) }

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.


Por veloz 3.0

import UIKit @objc protocol ADelegate : NSObjectProtocol { @objc optional func hi1() @objc optional func hi2(message1:String, message2:String) } class SomeObject : NSObject { weak var delegate:ADelegate? func run() { // single method if let methodHi1 = delegate?.hi1 { methodHi1() } else { print("fail h1") } // multiple parameters if let methodHi2 = delegate?.hi2 { methodHi2("superman", "batman") } else { print("fail h2") } } } class ViewController: UIViewController, ADelegate { let someObject = SomeObject() override func viewDidLoad() { super.viewDidLoad() someObject.delegate = self someObject.run() } // MARK: ADelegate func hi1() { print("Hi") } func hi2(message1: String, message2: String) { print("Hi /(message1) /(message2)") } }


Si el método que está probando está definido como un método opcional en un protocolo @objc (que suena como su caso), entonces use el patrón de encadenamiento opcional como:

if let result = object.method?(args) { /* method exists, result assigned, use result */ } else { ... }

Cuando el método se declara como return Void , simplemente use:

if object.method?(args) { ... }

Ver:

"Métodos de llamada a través de encadenamiento opcional"
Extracto de: Apple Inc. "The Swift Programming Language".
iBooks. https://itun.es/us/jEUH0.l


Simplemente 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.

@objc protocol ContactDetailsDelegate: class { optional func deleteContact(contact: Contact) -> NSError? } ... weak var delegate:ContactDetailsDelegate! if let deleteContact = delegate.deleteContact { deleteContact(contact) }


Swift 3:

protocolo

@objc protocol SomeDelegate { @objc optional func method() }

Objeto

class SomeObject : NSObject { weak var delegate:SomeObject? func delegateMethod() { if let delegateMethod = delegate?.method{ delegateMethod() }else { //Failed } } }


Uso guard let else , para que pueda hacer algunas cosas predeterminadas si el delegado func no está implementado.

@objc protocol ViewController2Delegate: NSObjectProtocol { optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnVoid string: String) optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnString string: String) -> String } class ViewController2: UIViewController { weak var delegate: ViewController2Delegate? @IBAction func onVoidButtonClicked(sender: AnyObject){ if (delegate != nil && delegate!.respondsToSelector(Selector("viewController2:didSomethingWithStringAndReturnVoid:"))) { NSLog("ReturnVoid is implemented") delegate!.viewController2!(self, didSomethingWithStringAndReturnVoid: "dummy") } else{ NSLog("ReturnVoid is not implemented") // Do something by default } } @IBAction func onStringButtonClicked(sender: AnyObject){ guard let result = delegate?.viewController2?(self, didSomethingWithStringAndReturnString: "dummy") else { NSLog("ReturnString is not implemented") // Do something by default return } NSLog("ReturnString is implemented with result: /(result)") } }


otra sintaxis posible por swift ..

if let delegate = self.delegate, method = delegate.somemethod{ method() }


Actualización 20 de marzo de 2017 para la sintaxis de Swift 3:

Si no le importa si existe el método opcional, simplemente llame a delegate?.optionalMethod?()

De lo contrario, usar guard es probablemente el mejor enfoque:

weak var delegate: SomeDelegateWithOptionals? func someMethod() { guard let method = delegate?.optionalMethod else { // optional not implemented alternativeMethod() return } method() }

Respuesta original:

Puede usar el enfoque "if let" para probar un protocolo opcional como este:

weak var delegate: SomeDelegateWithOptionals? func someMethod() { if let delegate = delegate { if let theMethod = delegate.theOptionalProtocolMethod? { theMethod() return } } // Reaching here means the delegate doesn''t exist or doesn''t respond to the optional method alternativeMethod() }