อีกคำตอบที่ล่าช้า แต่ไม่มีคำตอบใดที่มีอยู่ในคำถามนี้ที่ตอบคำถามของ OP ได้จริงนั่นคือ: ทำไมคุณถึงต้องใช้@objc
กับprivate
สมาชิกชั้นเรียนถ้า@objc
มีเพื่อโต้ตอบกับ Objective-C และสมาชิกที่มีปัญหา เป็นแบบส่วนตัวหมายความว่าแม้ว่าคุณจะมีรหัส Objective-C ในโปรเจ็กต์ของคุณ แต่ก็ไม่ควรมองเห็นสมาชิกได้ใช่ไหม
เหตุผลก็คือเนื่องจากเฟรมเวิร์กจำนวนมากถูกเขียนใน Objective-C บางครั้งคุณสมบัติของ Objective-C จึงจำเป็นสำหรับการโต้ตอบกับ API บางตัว
ตัวอย่างเช่นสมมติว่าฉันต้องการลงทะเบียนเพื่อรับการแจ้งเตือนผ่านDistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
เพื่อให้ได้ผลเราต้องสามารถรับตัวเลือกสำหรับsomethingHappened
วิธีการได้ อย่างไรก็ตามตัวเลือกเป็นแนวคิดของ Objective-C ดังนั้นหาก Objective-C มองไม่เห็นเมธอดแสดงว่าไม่มีตัวเลือก ดังนั้นแม้ว่าเมธอดจะเป็นแบบส่วนตัวและไม่ควรถูกเรียกโดยใช้รหัสภายนอกโดยพลการ แต่ก็จำเป็นต้องมี@objc
คำสั่งเพื่อให้DistributedNotification
โค้ดซึ่งเขียนด้วย Objective-C สามารถเรียกใช้ผ่านตัวเลือกได้
อีกกรณีหนึ่งที่@objc
จำเป็นคือการรองรับ Key-Value Coding (KVC) โดยเฉพาะอย่างยิ่งบน macOS ที่ใช้ KVC และ KVO เพื่อใช้งาน Cocoa Bindings KVC ก็เหมือนกับระบบอื่น ๆ ใน Cocoa ที่ใช้ใน Objective-C ซึ่งมีผลทำให้คุณสมบัติที่สอดคล้องกับ KVC ต้องสัมผัสกับรันไทม์ Objective-C ในบางครั้งคุณสมบัติที่สอดคล้องกับ KVC เป็นเรื่องส่วนตัว ตัวอย่างหนึ่งคือเมื่อคุณมีคุณสมบัติที่ส่งผลต่อคุณสมบัติอื่น ๆ :
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
ในกรณีนี้ทรัพย์สินที่เก็บไว้ของเราที่เกิดขึ้นจริงเป็นส่วนตัว แต่ขึ้นอยู่กับสถานที่ให้บริการซึ่งเราไม่เปิดเผยรหัสข้างนอกต้องส่งการแจ้งเตือนเมื่อทรัพย์สินส่วนตัวที่มีการปรับปรุง การทำเครื่องหมายทรัพย์สินส่วนตัวเป็น@objc
เราสามารถทำได้อย่างง่ายดายโดยตั้งค่าการอ้างอิง KVC มิฉะนั้นเราจะต้องเขียนโค้ดเพื่อส่งการแจ้งเตือนด้วยตนเองในทรัพย์สินส่วนตัวwillSet
และdidSet
ตัวจัดการ นอกจากนี้คุณสมบัติคงที่ที่แจ้งระบบ KVC ที่dependentProperty
ขึ้นอยู่กับoriginalProperty
ความต้องการที่จะเปิดเผยกับ Objective-C เพื่อให้ระบบ KVC ค้นหาและเรียกมัน แต่ไม่เกี่ยวข้องกับไคลเอนต์ของรหัสของเรา
นอกจากนี้ตัวควบคุมมุมมองในแอพ macOS ที่อัปเดตการควบคุมในมุมมองโดยใช้ Cocoa Bindings เป็นรายละเอียดการใช้งานอาจทำให้คุณสมบัติส่วนตัวบางอย่างสอดคล้องกับ KVC เพื่อผูกการควบคุมเหล่านั้นเข้ากับพวกเขา
ดังที่คุณเห็นมีหลายครั้งที่อาจต้องเปิดเผยเมธอดหรือคุณสมบัติกับ Objective-C เพื่อโต้ตอบกับเฟรมเวิร์กโดยไม่จำเป็นต้องให้ลูกค้ามองเห็นโค้ดของคุณ