การแก้ไขนั้นถูกต้อง - ไม่มีอะไรเกี่ยวกับตัวเลือกที่คุณสามารถเปลี่ยนแปลงได้เพื่อให้วิธีการที่อ้างถึงการสัมผัสกับ Objective-C
เหตุผลทั้งหมดสำหรับคำเตือนนี้ในครั้งแรกที่เป็นผลมาจากSE-0160 ก่อนหน้า Swift 4 internal
หรือสูงกว่าสมาชิกที่เข้ากันได้กับ Objective-C ของNSObject
คลาสที่สืบทอดถูกอนุมานว่าเป็น@objc
ดังนั้นจึงสัมผัสกับ Objective-C ดังนั้นจึงอนุญาตให้เรียกใช้โดยใช้ตัวเลือก (เนื่องจากรันไทม์ Obj-C เป็นสิ่งจำเป็นเพื่อค้นหาวิธีการ การใช้งานสำหรับตัวเลือกที่กำหนด)
อย่างไรก็ตามใน Swift 4 ไม่เป็นเช่นนั้นอีกต่อไป เฉพาะประกาศที่เฉพาะเจาะจงมากจะสรุปตอนนี้จะ@objc
ยกตัวอย่างเช่นการแทนที่ของ@objc
วิธีการใช้งานของ@objc
ความต้องการโปรโตคอลและการประกาศที่มีลักษณะที่บ่งบอกถึงเช่น@objc
@IBOutlet
แรงจูงใจเบื้องหลังสิ่งนี้ตามรายละเอียดในข้อเสนอที่เชื่อมโยงข้างต้นประการแรกคือเพื่อป้องกันไม่ให้เมธอดโอเวอร์โหลดในการNSObject
สืบทอดคลาสไม่ให้ชนกันเนื่องจากมีตัวเลือกที่เหมือนกัน ประการที่สองช่วยลดขนาดไบนารีโดยไม่ต้องสร้าง thunks สำหรับสมาชิกที่ไม่จำเป็นต้องสัมผัสกับ Obj-C และประการที่สามช่วยเพิ่มความเร็วของการเชื่อมโยงแบบไดนามิก
หากคุณต้องการให้สมาชิกเห็น Obj-C คุณต้องทำเครื่องหมายเป็น@objc
ตัวอย่างเช่น:
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(foo), for: .touchUpInside)
}
@objc func foo() {
// ...
}
}
(ผู้ย้ายข้อมูลควรทำสิ่งนี้ให้คุณโดยอัตโนมัติด้วยตัวเลือกเมื่อเรียกใช้โดยเลือกตัวเลือก "ย่อขนาดการอนุมาน")
ในการเปิดเผยกลุ่มสมาชิกต่อ Obj-C คุณสามารถใช้@objc extension
:
@objc extension ViewController {
// both exposed to Obj-C
func foo() {}
func bar() {}
}
สิ่งนี้จะเปิดเผยสมาชิกทั้งหมดที่กำหนดไว้ใน Obj-C และให้ข้อผิดพลาดกับสมาชิกใด ๆ ที่ไม่สามารถสัมผัสกับ Obj-C ได้ (เว้นแต่จะระบุไว้อย่างชัดเจนว่าเป็น@nonobjc
)
ถ้าคุณมีชั้นเรียนที่คุณต้องการทั้งหมดสมาชิก Obj-C เข้ากันได้กับได้สัมผัสกับ Obj-C คุณสามารถทำเครื่องหมายชั้นเป็น@objcMembers
:
@objcMembers
class ViewController: UIViewController {
// ...
}
ตอนนี้สมาชิกทั้งหมดที่สามารถอนุมานได้@objc
จะเป็น อย่างไรก็ตามฉันไม่แนะนำให้ทำเช่นนี้เว้นแต่คุณจะต้องการให้สมาชิกทุกคนสัมผัสกับ Obj-C เนื่องจากข้อเสียดังกล่าวข้างต้นของการเปิดเผยสมาชิกโดยไม่จำเป็น
@objc
คือตอนนี้จำเป็นเพื่อที่จะให้พวกเขาที่จะ Obj-C และดังนั้นจึงใช้กับตัวเลือก