Kolejna późna odpowiedź, ale żadna z istniejących odpowiedzi na to pytanie tak naprawdę nie odpowiada na pytanie PO, a mianowicie: dlaczego do cholery miałbyś używać @objc
na private
członku klasy, jeśli @objc
istnieje do interakcji z celem-C i tym członkiem jest prywatny, co oznacza, że nawet jeśli masz kod Objective-C w swoim projekcie, i tak nie powinien on widzieć członka?
Powodem jest to, że ponieważ wiele frameworków jest napisanych w Objective-C, czasami funkcje Objective-C są potrzebne do interakcji z niektórymi API.
Na przykład załóżmy, że chcę zarejestrować się w celu otrzymania powiadomienia przez DistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
Aby to zadziałało, musimy być w stanie uzyskać selektor dla somethingHappened
metody. Jednak selektory są koncepcją Objective-C, więc jeśli metoda nie jest widoczna dla Objective-C, nie ma selektora. Dlatego, nawet jeśli metoda jest prywatna i nie powinna być wywoływana przez dowolnego kodu z zewnątrz, to będzie potrzebować @objc
, aby dla DistributedNotification
kodu, który jest napisany w Objective-C, aby móc nazwać go za pomocą selektora.
Innym częstym przypadkiem, w którym @objc
jest to potrzebne, jest obsługa kodowania klucz-wartość (KVC), szczególnie w systemie macOS, gdzie KVC i KVO są używane do implementacji powiązań kakao. KVC, podobnie jak wiele innych systemów w kakao, jest zaimplementowane w Objective-C, co powoduje, że właściwości zgodne z KVC muszą być widoczne w środowisku wykonawczym Objective-C. Czasami ma sens, aby właściwości zgodne z KVC były prywatne. Jednym z przykładów jest sytuacja, gdy masz właściwość, która wpływa na inne właściwości:
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
W tym przypadku nasz rzeczywisty majątek przechowywany jest prywatny, ale własnością zależne, które nie narazić się do kodu zewnętrznego, musi wysłać swoje powiadomienia, gdy prywatna własność jest aktualizowana. Oznaczając własność prywatną jako @objc
, możemy to łatwo zrobić, konfigurując zależność KVC - w przeciwnym razie musielibyśmy napisać kod, aby ręcznie wysyłać powiadomienia w właściwościach prywatnych willSet
i didSet
programach obsługi. Ponadto właściwość statyczna, która informuje system KVC, od którego dependentProperty
jest zależny, originalProperty
musi być ujawniona Objective-C, aby system KVC i go znaleźć i wywołać, ale nie jest to istotne dla klientów naszego kodu.
Ponadto kontroler widoku w aplikacji macOS, który aktualizuje formanty w swoim widoku przy użyciu powiązań Cocoa jako szczegółów implementacji, może sprawić, że niektóre właściwości prywatne będą zgodne z KVC w celu powiązania z nimi tych formantów.
Jak widać, są chwile, kiedy metoda lub właściwość może wymagać ujawnienia Objective-C w celu interakcji z platformami, bez konieczności bycia widoczną dla klientów kodu.