Swift có hỗ trợ phản chiếu không? ví dụ: có một cái gì đó giống như valueForKeyPath:
và setValue:forKeyPath:
cho các đối tượng Swift?
Trên thực tế, nó thậm chí có một hệ thống kiểu động, giống như obj.class
trong Objective-C?
Swift có hỗ trợ phản chiếu không? ví dụ: có một cái gì đó giống như valueForKeyPath:
và setValue:forKeyPath:
cho các đối tượng Swift?
Trên thực tế, nó thậm chí có một hệ thống kiểu động, giống như obj.class
trong Objective-C?
Câu trả lời:
Có vẻ như có một số hỗ trợ phản ánh bắt đầu:
class Fruit {
var name="Apple"
}
reflect(Fruit()).count // 1
reflect(Fruit())[0].0 // "name"
reflect(Fruit())[0].1.summary // "Apple"
Từ ý chính của mchambers, tại đây: https://gist.github.com/mchambers/fb9da554898dae3e54f2
Mirror
thực sự trích dẫn từ IDE
nhiều lần.
_stdlib_getTypeName
có thể trợ giúp.
Nếu một lớp mở rộng NSObject
, thì tất cả tính năng động và nội tâm của Objective-C sẽ hoạt động. Điêu nay bao gôm:
Một thiếu sót của chức năng này là hỗ trợ các kiểu giá trị tùy chọn của Swift. Ví dụ, thuộc tính Int có thể được liệt kê và sửa đổi nhưng Int? thuộc tính không thể. Các loại tùy chọn có thể được liệt kê một phần bằng cách sử dụng phản xạ / MirrorType, nhưng vẫn không được sửa đổi.
Nếu một lớp không mở rộng NSObject
, thì chỉ phản xạ mới, rất hạn chế (và đang xử lý?) Mới hoạt động (xem phản xạ / MirrorType), bổ sung khả năng hạn chế để hỏi một trường hợp về lớp và thuộc tính của nó, nhưng không có tính năng bổ sung nào ở trên .
Khi không mở rộng NSObject, hoặc sử dụng chỉ thị '@objc', Swift mặc định là gửi tĩnh và dựa trên vtable. Điều này nhanh hơn, tuy nhiên, trong trường hợp không có máy ảo không cho phép chặn phương thức thời gian chạy. Việc đánh chặn này là một phần cơ bản của Cacao và cần thiết cho các loại tính năng sau:
Do đó, nó được khuyến nghị rằng clases trong các ứng dụng Cocoa / CocoaTouch được triển khai với Swift:
Tóm lược:
Dữ liệu tham khảo: Chi phí thực thi cho các lệnh gọi phương thức:
(hiệu suất thực tế phụ thuộc vào phần cứng, nhưng tỷ lệ sẽ vẫn tương tự).
Ngoài ra, thuộc tính động cho phép chúng tôi chỉ dẫn rõ ràng cho Swift rằng một phương thức nên sử dụng điều phối động và do đó sẽ hỗ trợ việc đánh chặn.
public dynamic func foobar() -> AnyObject {
}
Tài liệu nói về hệ thống kiểu động, chủ yếu là về
Type
và dynamicType
Xem Loại Metatype (trong Tham chiếu Ngôn ngữ)
Thí dụ:
var clazz = TestObject.self
var instance: TestObject = clazz()
var type = instance.dynamicType
println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"
Bây giờ giả sử TestObject
mở rộngNSObject
var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()
if let testObject = instance as? TestObject {
println("yes!") //prints "yes!"
}
Hiện tại, chưa có phản ánh nào được thực hiện.
CHỈNH SỬA: Tôi dường như đã sai, hãy xem câu trả lời của stevex. Có một số phản ánh chỉ đọc đơn giản cho các thuộc tính được tích hợp, có thể là để cho phép các IDE kiểm tra nội dung đối tượng.
Có vẻ như API phản chiếu Swift không phải là ưu tiên cao của Apple vào lúc này. Nhưng bên cạnh câu trả lời @stevex, có một chức năng khác trong thư viện tiêu chuẩn giúp ích.
Kể từ phiên bản beta 6, _stdlib_getTypeName
có tên kiểu bị xáo trộn của một biến. Dán cái này vào một sân chơi trống:
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))")
Đầu ra là:
TypeName0 = NSString
TypeName1 = _TtC13__lldb_expr_014PureSwiftClass
TypeName2 = _TtSi
TypeName3 = _TtSS
Mục nhập blog của Ewan Swick giúp giải mã các chuỗi này:
ví dụ: _TtSi
viết tắt của Int
kiểu nội bộ của Swift .
Không có reflect
từ khóa nào trong Swift 5, bây giờ bạn có thể sử dụng
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