Một câu trả lời muộn khác, nhưng không có câu trả lời hiện có nào cho câu hỏi này thực sự trả lời câu hỏi của OP, đó là: tại sao bạn lại cần sử dụng cái quái gì cho @objc
một private
thành viên trong lớp, nếu @objc
có để tương tác với Objective-C và thành viên được đề cập. là riêng tư, có nghĩa là ngay cả khi bạn có mã Objective-C trong dự án của mình, nó vẫn không thể nhìn thấy thành viên?
Lý do là vì nhiều khuôn khổ được viết bằng Objective-C, đôi khi các tính năng Objective-C là cần thiết để tương tác với một số API nhất định.
Ví dụ: giả sử tôi muốn đăng ký nhận thông báo qua DistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
Để điều này hoạt động, chúng ta cần có bộ chọn cho somethingHappened
phương thức. Tuy nhiên, bộ chọn là một khái niệm Objective-C, vì vậy nếu phương thức không hiển thị với Objective-C, nó không có bộ chọn. Do đó, ngay cả khi phương thức là private và không nên được gọi bằng mã bên ngoài tùy ý, nó sẽ cần một @objc
thứ tự cho DistributedNotification
mã, được viết bằng Objective-C, để có thể gọi nó thông qua bộ chọn của nó.
Một trường hợp phổ biến khác @objc
cần thiết là hỗ trợ Mã hóa khóa-giá trị (KVC), đặc biệt là trên macOS, nơi KVC và KVO được sử dụng để triển khai Liên kết ca cao. KVC, giống như nhiều hệ thống khác trong Cacao, được triển khai trong Objective-C, có tác dụng yêu cầu các thuộc tính tuân thủ KVC được hiển thị trong thời gian chạy Objective-C. Đôi khi, các thuộc tính tuân thủ KVC là riêng tư. Một ví dụ là khi bạn có một thuộc tính ảnh hưởng đến các thuộc tính khác:
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
Trong trường hợp này, thuộc tính được lưu trữ thực tế của chúng tôi là riêng tư, nhưng thuộc tính phụ thuộc mà chúng tôi để lộ ra bên ngoài mã cần gửi thông báo khi thuộc tính riêng được cập nhật. Bằng cách đánh dấu thuộc tính riêng là @objc
, chúng tôi có thể dễ dàng thực hiện điều đó bằng cách thiết lập phụ thuộc KVC — nếu không, chúng tôi sẽ phải viết mã để gửi thủ công các thông báo trong thuộc tính riêng willSet
và didSet
trình xử lý. Ngoài ra, thuộc tính tĩnh thông báo cho hệ thống KVC dependentProperty
phụ thuộc vào originalProperty
cần được tiếp xúc với Objective-C để hệ thống KVC tìm thấy nó và gọi nó, nhưng nó không liên quan đến các máy khách của mã của chúng tôi.
Ngoài ra, bộ điều khiển chế độ xem trong ứng dụng macOS cập nhật các điều khiển trong chế độ xem của nó bằng cách sử dụng Cocoa Bindings làm chi tiết triển khai có thể làm cho các thuộc tính riêng tư nhất định tuân thủ KVC để ràng buộc các điều khiển đó với chúng.
Vì vậy, như bạn thấy, đôi khi một phương thức hoặc thuộc tính có thể cần được tiếp xúc với Objective-C để tương tác với các khung công tác, mà không nhất thiết phải hiển thị cho khách hàng sử dụng mã của bạn.