Pesquisei no Google, mas não consegui descobrir qual é o equivalente rápido respondsToSelector:
.
Essa é a única coisa que pude encontrar ( alternativa rápida para o respondsToSelector :), mas não é muito relevante no meu caso, pois está verificando a existência do delegado, não tenho um delegado, só quero verificar se existe uma nova API ou não, quando em execução no dispositivo e, se não, voltar para uma versão anterior da API.
objective-c
swift
selector
Gruntcakes
fonte
fonte
NSClassFromString
erespondsToSelector
entre outras mecânicas para verificar a funcionalidade recém-implementada, tenho que acreditar que os mecanismos já estão em vigor ou já estarão lá antes do lançamento. Tente assistir aoAdvanced Interop...
vídeo da WWDC.if #available(...)
Swift 2.x para evitar o usorespondsToSelector
em primeiro lugar. Mas você sabia disso. ( apple.co/1SNGtMQ )Respostas:
Como mencionado, na Swift na maioria das vezes você pode obter o que precisa com o
?
operador desempacotador opcional . Isso permite que você chame um método em um objeto se e somente se o objeto existir (nãonil
) e o método for implementado.No caso em que você ainda precisa
respondsToSelector:
, ele ainda está lá como parte doNSObject
protocolo.Se você estiver chamando
respondsToSelector:
um tipo de Obj-C no Swift, ele funcionará da mesma maneira que você esperaria. Se você o estiver usando em sua própria classe Swift, precisará garantir que sua classe deriveNSObject
.Aqui está um exemplo de uma classe Swift que você pode verificar se responde a um seletor:
É importante que você não deixe de fora os nomes dos parâmetros. Neste exemplo, não
Selector("sleep::")
é o mesmo que .Selector("sleep:minutes:")
fonte
let x =
parte. Basicamente, aif let x = y
estrutura é desembrulhar valores opcionais (semelhantes a!
). Como você está seBool
recuperandorespondsToSelector
, o compilador está reclamando que o resultado não é um tipo opcional (Bool?
).var
declarados? Eles ainda respondem da mesma maneira? No Objective-C eu poderia fazerif ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }
por umasomeVar
propriedade. Funciona da mesma maneira comvar
s no Swift?Não há substituição Swift real.
Você pode verificar da seguinte maneira:
Isso chama o método
someMethod
apenas se definido no objetosomeObject
mas você pode usá-lo apenas para@objc
protocolos que declararam o método comooptional
.O Swift é inerentemente um idioma seguro, portanto, toda vez que você chama um método, o Swift precisa saber que o método existe. Nenhuma verificação de tempo de execução é possível. Você não pode simplesmente chamar métodos aleatórios em objetos aleatórios.
Mesmo no Obj-C, você deve evitar essas coisas sempre que possível, porque não funciona bem com o ARC (o ARC aciona avisos para
performSelector:
).No entanto, ao verificar as APIs disponíveis, você ainda pode usar
respondsToSelector:
, mesmo se Swift, se estiver lidando comNSObject
instâncias:fonte
respondsToSelector:
pois a recomendação da Apple é explicitamente que você deveria fazê-lo. Veja aquirespondsToSelector:
é realmente bom ter. Mas se você passar pela referência Swift, eles falam sobre o uso de subclasses para diferentes versões do sistema.if #available(iOS 10) {
e depois chamamos o método diretamente.Atualize 20 de março de 2017 para a sintaxe do Swift 3:
Se você não se importa se o método opcional existe, basta chamar
delegate?.optionalMethod?()
Caso contrário, usar
guard
é provavelmente a melhor abordagem:Resposta original:
Você pode usar a abordagem "if let" para testar um protocolo opcional como este:
fonte
let theMethod = delegate.userNotificationCenter(_:willPresent:withCompletionHandler:)
Parece que você precisa definir seu protocolo como subprotocolo de NSObjectProtocol ... então você obterá o método respondsToSelector
observe que apenas especificar @objc não foi suficiente. Você também deve ter cuidado para que o delegado real seja uma subclasse do NSObject - que no Swift pode não ser.
fonte
Se o método que você está testando for definido como um método opcional em um protocolo @objc (que parece o seu caso), use o padrão de encadeamento opcional como:
Quando o método for declarado como retornando
Void
, basta usar:Vejo:
fonte
if object.method?(args) { ... }
- a chamada do método, quando existe, irá devolverVoid
o que não énil
object
tiver um tipoAnyObject
, você poderá testar qualquer método @objc.As funções são tipos de primeira classe no Swift, para que você possa verificar se uma função opcional definida em um protocolo foi implementada comparando-a com zero:
fonte
Para swift3
Se você quiser chamar o método, execute o código abaixo.
self.delegate?.method?()
fonte
No Swift 2, a Apple introduziu um novo recurso chamado
API availability checking
, que pode ser um substituto para orespondsToSelector:
método. A comparação de trechos de código a seguir é copiada da WWDC2015 Session 106 What's New in Swift, que eu pensei que poderia ajudá-lo, verifique se você precisar saber mais.fonte
respondsToSelector
abordagem no Swift. Isso também ocorre porque a verificação do seletor não era a melhor solução para esse problema (verificação da disponibilidade) em primeiro lugar.For swift 3.0
fonte
Atualmente (Swift 2.1), você pode verificá-lo usando três maneiras:
Usando '?' respondido por @Sulthan
E usando o
as?
operador:Basicamente, depende do que você está tentando alcançar:
fonte
Eu apenas implementei isso em um projeto, veja o código abaixo. Como mencionado por @Christopher Pickslay, é importante lembrar que as funções são cidadãos de primeira classe e, portanto, podem ser tratadas como variáveis opcionais.
fonte
outra sintaxe possível por swift ..
fonte
Quando comecei a atualizar meu projeto antigo para o Swift 3.2, só precisava alterar o método de
para:
fonte
Eu uso
guard let else
, para que possa fazer algumas coisas padrão se a função delegada não for implementada.fonte
Swift 3:
protocolo
Objeto
fonte
O equivalente é o? operador:
importantMethod só será chamado se myQuestionableObject existir e implementá-lo.
fonte
?
depoisimportantMethod