#swift #reflection #introspection #swift-class
#swift #отражение #самоанализ #swift-класс
Вопрос:
Я пытаюсь понять возможности перегиба swift. У меня есть родительский Passport
класс, дочерний элемент которого ( User
) реализует протокол Clonable
, однако при самоанализе дочернего значения проверка не выполняется child.value is Clonable
. Кто-нибудь может это объяснить?
extension Clonable {
func clone() -> Self? {
if let me = self as? SimpleInit {
let new = type(of: me).init()
let mirror = Mirror(reflecting: self)
for child in mirror.children {
if let kp = child.label, let new = new as? NSObject {
if child.value is Clonable, let value = child.value as? Clonable { // this should be true
print("cloning (child.value) for keypath (kp)")
new.setValue(value.clone(), forKeyPath: kp)
} else {
print("not cloning (child.value) for keypath (kp)")
new.setValue(child.value, forKeyPath: kp)
}
}
}
return new as? Self
}
return nil
}
}
class Passport: NSObject, Clonable, SimpleInit, CustomReflectable {
var customMirror: Mirror {
return Mirror(self, children: ["user": user])
}
@objc var user: User?
required override init() {
}
func printMe() {
user?.printMe()
}
}
class User: NSObject, Clonable, SimpleInit, CustomReflectable {
var customMirror: Mirror {
return Mirror(self, children: ["name": name])
}
@objc var id: Int
@objc var name: String?
required override init() {
print("init user")
id = Int(arc4random())
}
func printMe() {
print("id (id) name (name)")
}
}
let passport = Passport()
passport.user = User()
passport.user?.name = "John"
let clone = passport.clone()
passport.printMe()
clone?.printMe()
Это результат:
init user // should be called second time when user gets cloned.
not cloning Optional(<__lldb_expr_92.User: 0x6000039d6420>) for keypath user
id 2046302380 name Optional("John")
id 2046302380 name Optional("John")
Комментарии:
1. Вы пробовали
if let value = child.value as? Clonable {
, этого должно быть достаточно для этого единственного теста2. Да, я сделал, не работает 🙁