Swift รองรับการสะท้อนหรือไม่? เช่นมีบางอย่างเช่นvalueForKeyPath:
และsetValue:forKeyPath:
สำหรับวัตถุ Swift หรือไม่?
จริงๆแล้วมันมีระบบประเภทไดนามิกobj.class
หรือไม่เช่นใน Objective-C หรือไม่?
Swift รองรับการสะท้อนหรือไม่? เช่นมีบางอย่างเช่นvalueForKeyPath:
และsetValue:forKeyPath:
สำหรับวัตถุ Swift หรือไม่?
จริงๆแล้วมันมีระบบประเภทไดนามิกobj.class
หรือไม่เช่นใน Objective-C หรือไม่?
คำตอบ:
ดูเหมือนว่ามีจุดเริ่มต้นของการสนับสนุนการสะท้อนกลับ:
class Fruit {
var name="Apple"
}
reflect(Fruit()).count // 1
reflect(Fruit())[0].0 // "name"
reflect(Fruit())[0].1.summary // "Apple"
จากส่วนสำคัญของ mchambers ที่นี่: https://gist.github.com/mchambers/fb9da554898dae3e54f2
Mirror
จริงๆแล้วพิธีสารจะพูดคำนี้IDE
หลายครั้ง
_stdlib_getTypeName
จะช่วยได้อย่างไร
ถ้าคลาสขยายออกไปNSObject
การวิปัสสนาและพลวัตของ Objective-C ทั้งหมดจะทำงาน ซึ่งรวมถึง:
ข้อบกพร่องประการหนึ่งของฟังก์ชันนี้คือการรองรับประเภทค่าที่เป็นทางเลือกของ Swift ตัวอย่างเช่นคุณสมบัติ Int สามารถแจกแจงและแก้ไขได้ แต่ Int? คุณสมบัติไม่ได้ สามารถระบุประเภทที่เป็นทางเลือกได้บางส่วนโดยใช้ reflect / MirrorType แต่ยังไม่ได้แก้ไข
หากคลาสไม่ขยายออกNSObject
จะมีเพียงการสะท้อนแบบใหม่ที่ จำกัด มาก (และกำลังดำเนินการ?) เท่านั้นที่ทำงานได้ (ดู reflect / MirrorType) ซึ่งจะเพิ่มความสามารถที่ จำกัด ในการถามอินสแตนซ์เกี่ยวกับคลาสและคุณสมบัติของคลาส แต่ไม่มีคุณสมบัติเพิ่มเติมใด ๆ ข้างต้น .
เมื่อไม่ขยาย NSObject หรือใช้คำสั่ง '@objc' Swift จะตั้งค่าเริ่มต้นเป็นการจัดส่งแบบคงที่และแบบ vtable เร็วกว่าอย่างไรก็ตามในกรณีที่ไม่มีเครื่องเสมือนไม่อนุญาตให้มีการสกัดกั้นเมธอดรันไทม์ การสกัดกั้นนี้เป็นส่วนพื้นฐานของโกโก้และจำเป็นสำหรับคุณสมบัติประเภทต่อไปนี้:
ดังนั้นจึงแนะนำให้ใช้ clases ใน Cocoa / CocoaTouch กับ Swift:
สรุป:
ข้อมูลอ้างอิง: ค่าใช้จ่ายในการดำเนินการสำหรับการเรียกใช้เมธอด:
(ประสิทธิภาพจริงขึ้นอยู่กับฮาร์ดแวร์ แต่อัตราส่วนจะยังคงใกล้เคียงกัน)
นอกจากนี้แอตทริบิวต์ไดนามิกยังช่วยให้เราสามารถสั่ง Swift ได้อย่างชัดเจนว่าเมธอดควรใช้การจัดส่งแบบไดนามิกดังนั้นจึงรองรับการสกัดกั้น
public dynamic func foobar() -> AnyObject {
}
เอกสารนี้พูดเกี่ยวกับระบบประเภทไดนามิกส่วนใหญ่เกี่ยวกับ
Type
และ dynamicType
ดูประเภท Metatype (ในการอ้างอิงภาษา)
ตัวอย่าง:
var clazz = TestObject.self
var instance: TestObject = clazz()
var type = instance.dynamicType
println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"
ตอนนี้สมมติว่าTestObject
ขยายNSObject
var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()
if let testObject = instance as? TestObject {
println("yes!") //prints "yes!"
}
ปัจจุบันไม่มีการสะท้อนกลับมาใช้
แก้ไข:เห็นได้ชัดว่าฉันคิดผิดดูคำตอบของ stevex มีการสะท้อนแบบอ่านอย่างเดียวง่ายๆสำหรับคุณสมบัติที่สร้างขึ้นซึ่งอาจเพื่อให้ IDEs ตรวจสอบเนื้อหาวัตถุ
ดูเหมือนว่า API การสะท้อนของ Swift จะไม่ใช่สิ่งสำคัญสำหรับ Apple ในขณะนี้ แต่นอกจากคำตอบ @stevex แล้วยังมีฟังก์ชันอื่นในไลบรารีมาตรฐานที่ช่วยได้
เมื่อเบต้า 6 _stdlib_getTypeName
ได้รับชื่อชนิดของตัวแปร วางสิ่งนี้ลงในสนามเด็กเล่นที่ว่างเปล่า:
import Foundation
class PureSwiftClass {
}
var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"
println( "TypeName0 = \(_stdlib_getTypeName(myvar0))")
println( "TypeName1 = \(_stdlib_getTypeName(myvar1))")
println( "TypeName2 = \(_stdlib_getTypeName(myvar2))")
println( "TypeName3 = \(_stdlib_getTypeName(myvar3))")
ผลลัพธ์คือ:
TypeName0 = NSString
TypeName1 = _TtC13__lldb_expr_014PureSwiftClass
TypeName2 = _TtSi
TypeName3 = _TtSS
รายการบล็อกของ Ewan Swickช่วยในการถอดรหัสสตริงเหล่านี้:
เช่น_TtSi
ย่อมาจากInt
ประเภทภายในของ Swift
คุณอาจต้องการพิจารณาใช้toString ()แทน เป็นสาธารณะและใช้งานได้เหมือนกับ_stdlib_getTypeName ()โดยมีข้อแตกต่างที่ใช้งานได้กับAnyClassเช่นใน Playground enter
class MyClass {}
toString(MyClass.self) // evaluates to "__lldb_expr_49.MyClass"
ไม่มีreflect
คีย์เวิร์ดใน Swift 5 ตอนนี้คุณสามารถใช้ได้
struct Person {
var name="name"
var age = 15
}
var me = Person()
var mirror = Mirror(reflecting: me)
for case let (label?, value) in mirror.children {
print (label, value)
}
json
deserialization