No Swift, vejo alguns métodos como:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
Eu queria saber quando usar @objc? Eu li alguns documentos, mas eles estão dizendo que quando você quiser que seja possível chamá-lo em Objective-C, você deve adicionar o sinalizador @objc
No entanto, esta é uma função privada no Swift, o que o @obj faz?
Respostas:
privado significa que é visível apenas em Swift. então use @objc para ficar visível em Objective-C. Se você tem uma função para selecionar uma função privada no swift, ela é necessária.
Consulte: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
fonte
@objc private func doubleTapGestureRecognized
, de que adianta ter @objc e private? Você está dizendo que as classes Objective-C podem sobrescrever doubleTapGestureRecognized?Outra resposta tardia, mas nenhuma das respostas existentes nesta pergunta realmente responde à pergunta do OP, que é: por que diabos você precisaria usar
@objc
em umprivate
membro da classe, se@objc
existe para interação com Objective-C e o membro em questão é privado, o que significa que mesmo se você tiver o código Objective-C em seu projeto, ele não deverá ser capaz de ver o membro de qualquer maneira?A razão é que, como muitos dos frameworks são escritos em Objective-C, às vezes os recursos do Objective-C são necessários para interagir com certas APIs.
Por exemplo, suponha que eu queira me registrar para receber uma notificação por meio de
DistributedNotificationCenter
:DistributedNotificationCenter.default.addObserver(self, selector: #selector(somethingHappened(_:)), name: someNotification, object: nil)
Para que isso funcione, precisamos ser capazes de obter o seletor para o
somethingHappened
método. No entanto, os seletores são um conceito do Objective-C, portanto, se o método não for visível para o Objective-C, ele não terá um seletor. Portanto, mesmo que o método seja privado e não deva ser chamado por um código externo arbitrário, ele precisará de um@objc
in para que oDistributedNotification
código, que está escrito em Objective-C, seja capaz de chamá-lo por meio de seu seletor.Outro caso comum em que
@objc
é necessário é oferecer suporte a Key-Value Coding (KVC), especialmente no macOS, onde KVC e KVO são usados para implementar vinculações Cocoa. KVC é, como muitos outros sistemas em Cocoa, implementado em Objective-C, o que tem o efeito de exigir que as propriedades compatíveis com KVC sejam expostas ao tempo de execução Objective-C. Às vezes, faz sentido que as propriedades compatíveis com KVC sejam privadas. Um exemplo é quando você tem uma propriedade que afeta outras propriedades:@objc private dynamic var originalProperty: String @objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [ #keyPath(originalProperty) ] @objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
Neste caso, a nossa propriedade real armazenado é privado, mas a propriedade dependente, o que nós não expor para o código fora, precisa enviar suas notificações quando a propriedade privada é atualizado. Ao marcar a propriedade privada como
@objc
, podemos fazer isso facilmente configurando uma dependência KVC - caso contrário, teríamos que escrever código para enviar manualmente as notificações na propriedade privadawillSet
e nosdidSet
manipuladores. Além disso, a propriedade estática que informa o sistema KVC de quedependentProperty
dependeoriginalProperty
precisa ser exposta ao Objective-C para que o sistema KVC o encontre e o chame, mas não é relevante para os clientes do nosso código.Além disso, um controlador de visualização em um aplicativo macOS que atualiza os controles em sua visualização usando Cocoa Bindings como um detalhe de implementação pode tornar certas propriedades privadas compatíveis com KVC para vincular esses controles a elas.
Como você pode ver, há momentos em que um método ou propriedade pode precisar ser exposto ao Objective-C para interagir com os frameworks, sem necessariamente precisar estar visível para os clientes do seu código.
fonte
@objc / dynamic
É para compatibilidade: Depois de importar seu arquivo / código Swift para um projeto baseado em Objective-C.
E use-o se quiser que sua propriedade / método seja acessado pelo código ou classe Objective-C.
Na maioria das vezes, isso acontece quando você está subclassificando uma classe Swift da classe base Objective-C.
Aqui a documentação da maçã que diz sobre
@objc
.Usando Swift de Objective-C
Compatibilidade de interoperabilidade de linguagem
Links atualizados:
Parece que os links foram atualizados pela apple.
fonte
@objc é um atributo de classe, então você usa
@objc public class MyClass
Ele expõe os métodos da classe para classes Objective C, então você só vai usá-lo se sua classe contiver funções públicas
fonte
Uma resposta tardia, mas esse
@objc
comportamento está mudando um pouco a partir do Swift 4 (que saiu no Xcode 9, que geralmente foi lançado há 10 dias).No Swift 4, alguns casos de inferência de
@objc
são removidos. Isso significa apenas que, em alguns casos adicionais, onde antes do@objc
cabeçalho ser inferido pelo compilador Swift, ele não foi inferido no Swift 4.Leia mais na proposta de evolução do Swift sobre essa mudança
Como foi mencionado, em geral
@objc
é expor certos métodos para o tempo de execução do Objective-C, que faz parte da interoperabilidade da linguagem do Swift.fonte
@objc
@objc
expõe uma declaração paraObjective-C runtime
. Vamos dar uma olhada no#selector
recurso do Swift para usar um tempo de execução Objective-C. Neste caso, você pode definir o seu Swift@objc private func
[Mais]Para usar as funções do Swift em Objective-C:
NSObject
Mark Swift's:
uma. somente
@objcMembers
classe - para expor todos ospublic
construtores , campos e métodos . Também é aplicável para subclassesb.
@objc
classe / enum / protocolo (exceto estrutura ) [Tipo Nomeado]@objc
classe (opcional) - para expor um padrãopublic init()
. Ou@objc(<custom_name>)
para configurar um nome personalizado para a classe.@objc
construtores , campos e métodos - para expô-los seletivamenteO método do Swift estará disponível na próxima nomenclatura:
<swiftName>With<firstArgument>:<secondArgument>:
Por exemplo:
public func printHelloWorld(arg1: String, arg2:String) //is reached through: [someObject printHelloWorldWithArg1: arg2:];
[
@objc
edynamic
]fonte