En Swift, veo algunos métodos como:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
Me preguntaba, ¿cuándo usar @objc? Leí algunos documentos, pero dicen que cuando desee que se pueda llamar en Objective-C, debe agregar la bandera @objc
Sin embargo, esta es una función privada en Swift, ¿qué hace @obj?

Respuestas:
privado significa que solo es visible en Swift. así que use @objc para ser visible en Objective-C. Si tiene una función para seleccionar una función privada en rápido, es necesaria.
Ver: 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
fuente
@objc private func doubleTapGestureRecognized, cuál es el punto de tener tanto @objc y privada? ¿Estás diciendo que las clases de Objective-C pueden sobrescribir doubleTapGestureRecognized?Otra respuesta tardía, pero ninguna de las respuestas existentes en esta pregunta realmente responde a la pregunta del OP, que es: ¿por qué diablos necesitaría usarla
@objcen unprivatemiembro de la clase, si@objcestá allí para interactuar con Objective-C y el miembro en cuestión? es privado, lo que significa que incluso si tiene código Objective-C en su proyecto, ¿no debería poder ver al miembro de todos modos?La razón es que, debido a que muchos de los marcos están escritos en Objective-C, a veces se necesitan características de Objective-C para interactuar con ciertas API.
Por ejemplo, supongamos que quiero registrarme para recibir una notificación a través de
DistributedNotificationCenter:DistributedNotificationCenter.default.addObserver(self, selector: #selector(somethingHappened(_:)), name: someNotification, object: nil)Para que esto funcione, necesitamos poder obtener el selector para el
somethingHappenedmétodo. Sin embargo, los selectores son un concepto de Objective-C, por lo que si el método no es visible para Objective-C, no tiene selector. Por lo tanto, incluso si el método es privado y no debe ser llamado por código externo arbitrario, necesitará un@objcorden para que elDistributedNotificationcódigo, que está escrito en Objective-C, pueda llamarlo a través de su selector.Otro caso común en el que
@objcse necesita es admitir la codificación de valores clave (KVC), especialmente en macOS, donde se utilizan KVC y KVO para implementar Cocoa Bindings. KVC, como muchos otros sistemas en Cocoa, está implementado en Objective-C, lo que tiene el efecto de requerir que las propiedades compatibles con KVC estén expuestas al tiempo de ejecución de Objective-C. A veces, tiene sentido que las propiedades compatibles con KVC sean privadas. Un ejemplo es cuando tiene una propiedad que afecta a otras propiedades:@objc private dynamic var originalProperty: String @objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [ #keyPath(originalProperty) ] @objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }En este caso, nuestra propiedad almacenada real es privada, pero la propiedad dependiente, que sí exponemos en el código externo, tiene que enviar sus notificaciones cuando la propiedad privada se actualiza. Al marcar la propiedad privada como
@objc, podemos hacerlo fácilmente configurando una dependencia de KVC; de lo contrario, tendríamos que escribir código para enviar manualmente las notificaciones en los controladoreswillSety la propiedad privadadidSet. Además, la propiedad estática que informa al sistema KVC del quedependentPropertydependeoriginalPropertydebe estar expuesta a Objective-C para que el sistema KVC lo encuentre y lo llame, pero no es relevante para los clientes de nuestro código.Además, un controlador de vista en una aplicación macOS que actualiza los controles en su vista usando Cocoa Bindings como un detalle de implementación puede hacer que ciertas propiedades privadas sean compatibles con KVC para vincular esos controles a ellos.
Entonces, como puede ver, hay ocasiones en las que un método o propiedad puede necesitar exponerse a Objective-C para interactuar con los marcos, sin necesariamente tener que ser visible para los clientes de su código.
fuente
@objc / dinámico
Es por compatibilidad: una vez que importe su archivo / código Swift en un proyecto basado en Objective-C.
Y utilícelo si desea que el código o la clase de Objective-C acceda a su propiedad / método.
La mayoría de las veces sucede cuando está subclasificando una clase Swift de la clase base Objective-C.
Aquí la documentación de Apple que dice sobre
@objc.Usando Swift desde Objective-C
Compatibilidad de interoperabilidad de idiomas
Enlaces actualizados:
parece que Apple ha actualizado los enlaces.
fuente
@objc es un atributo de clase, por lo que usa
@objc public class MyClassExpone los métodos de la clase a las clases de Objective C, por lo que solo lo usará si su clase contiene funciones públicas
fuente
Una respuesta tardía, pero este
@objccomportamiento está cambiando ligeramente a partir de Swift 4 (que salió en Xcode 9, que generalmente se lanzó hace 10 días).En Swift 4,
@objcse eliminan algunos casos de inferencia de . Esto solo significa que en algunos casos adicionales en los que antes de que el@objccompilador de Swift infiera el encabezado, no se infiere en Swift 4.Leer más en la propuesta de evolución Swift sobre este cambio
Como se ha mencionado, en general se
@objctrata de exponer ciertos métodos al tiempo de ejecución de Objective-C, que es parte de la interoperabilidad de Swift con el lenguaje.fuente
@objc@objcexpone una declaración aObjective-C runtime. Echemos un vistazo a la#selectorfunción de Swift para usar un tiempo de ejecución de Objective-C. En este caso, puede definir su Swift@objc private func[Más]Para usar las funciones de Swift de Objective-C:
NSObjectDe Mark Swift:
a. solo
@objcMembersclase : para exponer todos lospublicconstructores , campos y métodos . También es aplicable para subclases.segundo.
@objcclase / enumeración / protocolo (excepto estructura ) [Tipo con nombre]@objcclass (opcional): para exponer un archivopublic init(). O@objc(<custom_name>)para configurar un nombre personalizado para la clase.@objcconstructores , campos y métodos - para exponerlos selectivamenteEl método de Swift estará disponible con el siguiente nombre:
<swiftName>With<firstArgument>:<secondArgument>:Por ejemplo:
public func printHelloWorld(arg1: String, arg2:String) //is reached through: [someObject printHelloWorldWithArg1: arg2:];[
@objcydynamic]fuente