问题
在swift4
中使用kvc
:
class Person: NSObject {
var dog: Dog?
}
class Dog: NSObject {
var name: String
init(name: String) {
self.name = name
}
}
let whiteDog = Dog(name: "white")
let person = Person()
person.setValue(whiteDog, forKey: "dog")
let myDog: Dog = person.value(forKeyPath: "dog") as! Dog
print(myDog.name)
复制代码
然后会发生crash得到如下信息:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<RXLearn.Person 0x1c4002610> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key dog.'
复制代码
原因
swift
为了性能优化,需要标记为@objc
的属性才能使用kvc
,所以这样:
class Person: NSObject {
@objc var dog: Dog?
}
复制代码
swift4 新功能
无论结构体还是类都可以使用这个方法[keyPath: ReferenceWritableKeyPath<Root, Value>]
进行取赋值。
class Person {
var dog: Dog
init(dog: Dog) {
self.dog = dog
}
}
class Dog {
var name: String
init(name: String) {
self.name = name
}
}
//
let blackDog = Dog(name: "black")
let whiteDog = Dog(name: "white")
let person = Person(dog: blackDog)
person[keyPath: \Person.dog] = whiteDog
let mydog = person[keyPath: name]
print(mydog.name) // 打印white
复制代码
将person
改为结构体依然可以:
struct Person {
var dog: Dog
init(dog: Dog) {
self.dog = dog
}
}
复制代码