Eine weitere späte Antwort, aber keine der vorhandenen Antworten auf diese Frage beantwortet wirklich die Frage des OP: Warum zum Teufel müssten Sie @objc
ein private
Klassenmitglied verwenden, wenn @objc
es für die Interaktion mit Objective-C und dem betreffenden Mitglied vorhanden ist? ist privat, was bedeutet, dass selbst wenn Sie Objective-C-Code in Ihrem Projekt haben, es das Mitglied sowieso nicht sehen kann?
Der Grund dafür ist, dass, da viele der Frameworks in Objective-C geschrieben sind, manchmal Objective-C-Funktionen erforderlich sind, um mit bestimmten APIs zu interagieren.
Angenommen, ich möchte mich für eine Benachrichtigung registrieren über DistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
Damit dies funktioniert, müssen wir in der Lage sein, den Selektor für die somethingHappened
Methode zu erhalten. Selektoren sind jedoch ein Objective-C-Konzept. Wenn die Methode für Objective-C nicht sichtbar ist, verfügt sie nicht über einen Selektor. Daher kann , selbst wenn die Methode privat ist und nicht durch willkürlichen außerhalb Code aufgerufen werden soll, wird es eine müssen , @objc
um für den DistributedNotification
Code, der in Objective-C geschrieben ist, nennt es über seine Wähler zu können.
Ein weiterer häufiger Fall, der @objc
benötigt wird, ist die Unterstützung der Schlüsselwertcodierung (KVC), insbesondere unter macOS, wo KVC und KVO zur Implementierung von Kakaobindungen verwendet werden. KVC wird wie viele andere Systeme in Cocoa in Objective-C implementiert, wodurch KVC-kompatible Eigenschaften für die Objective-C-Laufzeit verfügbar gemacht werden müssen. Manchmal ist es sinnvoll, dass KVC-konforme Eigenschaften privat sind. Ein Beispiel ist, wenn Sie eine Eigenschaft haben, die andere Eigenschaften beeinflusst:
@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 diesem Fall ist unsere tatsächlich gespeicherten Eigenschaft privat, aber die abhängige Eigenschaft, die wir tun , um außerhalb Code aufzudecken, muss seine Benachrichtigungen senden , wenn das Privateigentum aktualisiert. Durch Markieren der Privateigenschaft als @objc
können wir dies leicht tun, indem wir eine KVC-Abhängigkeit einrichten. Andernfalls müssten wir Code schreiben, um die Benachrichtigungen in den Privateigentumern willSet
und didSet
Handlern manuell zu senden . Darüber hinaus muss die statische Eigenschaft, die das von dependentProperty
abhängige KVC-System informiert originalProperty
, für Objective-C verfügbar gemacht werden, damit das KVC-System es finden und aufrufen kann. Für Kunden unseres Codes ist es jedoch nicht relevant.
Außerdem kann ein Ansichtscontroller in einer macOS-App, der Steuerelemente in seiner Ansicht mithilfe von Cocoa Bindings als Implementierungsdetail aktualisiert, bestimmte private Eigenschaften KVC-kompatibel machen, um diese Steuerelemente an sie zu binden.
Wie Sie sehen, kann es vorkommen, dass eine Methode oder Eigenschaft für Objective-C verfügbar gemacht werden muss, um mit den Frameworks zu interagieren, ohne dass dies für Clients Ihres Codes unbedingt sichtbar sein muss.