Un'altra risposta tardiva, ma nessuna delle risposte esistenti su questa domanda risponde davvero alla domanda dell'OP, che è: perché diamine dovresti usare @objcsu un privatemembro della classe, se @objcè lì per l'interazione con Objective-C e il membro in questione è privato, il che significa che anche se hai codice Objective-C nel tuo progetto, non dovrebbe comunque essere in grado di vedere il membro?
Il motivo è che, poiché molti dei framework sono scritti in Objective-C, a volte sono necessarie funzionalità Objective-C per interagire con determinate API.
Ad esempio, supponiamo che io voglia registrarmi per una notifica tramite DistributedNotificationCenter:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
Affinché funzioni, dobbiamo essere in grado di ottenere il selettore per il somethingHappenedmetodo. Tuttavia, i selettori sono un concetto Objective-C, quindi se il metodo non è visibile a Objective-C, non dispone di un selettore. Pertanto, anche se il metodo è privato e non deve essere chiamato da codice esterno arbitrario, avrà bisogno di una @objcaffinché il DistributedNotificationcodice, che è scritto in Objective-C, possa chiamarlo tramite il suo selettore.
Un altro caso comune in cui @objcè necessario è supportare KVC (Key-Value Coding), specialmente su macOS, dove KVC e KVO vengono utilizzati per implementare Cocoa Bindings. KVC è, come molti altri sistemi in Cocoa, implementato in Objective-C, che ha l'effetto di richiedere che le proprietà conformi a KVC siano esposte al runtime Objective-C. A volte, ha senso che le proprietà conformi a KVC siano private. Un esempio è quando hai una proprietà che influisce su altre proprietà:
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
In questo caso, la nostra proprietà effettivo memorizzato è privata, ma la proprietà dipendente, che noi facciamo esponiamo al codice esterno, ha bisogno di inviare le sue notifiche quando la proprietà privata viene aggiornato. Contrassegnando la proprietà privata come @objc, possiamo farlo facilmente impostando una dipendenza KVC, altrimenti dovremmo scrivere il codice per inviare manualmente le notifiche nella proprietà privata willSete nei didSetgestori. Inoltre, la proprietà statica che informa il sistema KVC da cui dependentPropertydipende originalPropertydeve essere esposta a Objective-C in modo che il sistema KVC lo trovi e lo chiami, ma non è rilevante per i client del nostro codice.
Inoltre, un controller di visualizzazione in un'app macOS che aggiorna i controlli nella sua vista utilizzando Cocoa Bindings come dettaglio di implementazione può rendere alcune proprietà private conformi a KVC per associare tali controlli a loro.
Quindi, come puoi vedere, ci sono momenti in cui un metodo o una proprietà potrebbe dover essere esposto a Objective-C per interagire con i framework, senza necessariamente dover essere visibile ai client del tuo codice.