問題
在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
}
}
複製程式碼