如何在 Swift 4.0 中使用键值编码?
How do I use Key-Value Coding in Swfit 4.0?
我以前没用过Swift4,也不知道里面怎么用KVC。
我尝试用字典创建模型,这里是代码:
class Person : NSObject {
var name: String = ""
var age: Int = 0
init(dict: [String : Any]) {
super.init()
self.setValuesForKeys(dict)
}
}
let dict: [String : Any] = ["name" : "Leon", "age" : 18]
let p = Person(dict: dict)
print(p.name, p.age)
我有两个问题:
1. 为什么我不用AnyObject
? "Leon"
和18
被推断为String
和Int
,它在KVC中使用吗?
2. @objc var name: String = ""
这个表格可以用,但是看不懂
感谢大家的帮助。
您的代码
var name: String = ""
var age: Int = 0
当你确定它的类型时,你可以像这样编写相同的代码。
var name = ""
var age = 0
Any一般用于所有类型(函数类型和可选类型),而AnyObject用于Class类型。
@objc 有不同的含义,当您在 swift class 中使用 @objc 时,该代码在 objective-c 中可用。您应该使用@objc 属性来指定与 objective-c class 相同的结果,旧的存档可以被新的 swift class.
[=27= 替换]
要在 Swift 4 中实现对 属性 的 KVC 支持,您需要做两件事:
由于目前的KVC实现是在Objective-C中写的,你需要在你的属性上加上@objc
注解,这样Objective-C才能看到它。这也意味着 属性 的类型需要与 Objective-C.
兼容
除了将 属性 公开给 Objective-C 之外,您还需要设置通知,以便在 属性 更改时通知观察者.有以下三种方法:
对于存储属性,最简单的做法是添加 dynamic
关键字,如下所示:
@objc dynamic var foo: String
这将允许 Cocoa 使用 Objective-C 魔法自动为您生成所需的通知,这通常是您想要的。但是,如果需要更精细的控制,也可以手动编写通知代码:
@objc private static let automaticallyNotifiesObserversOfFoo = false
@objc var foo: String {
willSet { self.willChangeValue(for: \.foo) }
didSet { self.didChangeValue(for: \.foo) }
}
automaticallyNotifiesObserversOf<property name>
属性 是为了向 KVC/KVO 系统表明我们正在自己处理通知,Cocoa 不应该尝试为其生成通知我们
最后,如果你的 属性 没有被存储,而是依赖于其他一些 属性 或属性,你需要像这样实现一个 keyPathsForValuesAffecting<your property name here>
方法:
@objc dynamic var foo: Int
@objc dynamic var bar: Int
@objc private static let keyPathsForValuesAffectingBaz: Set<String> = [
#keyPath(foo), #keyPath(bar)
]
@objc var baz: Int { return self.foo + self.bar }
在上面的示例中,baz
属性 的观察者将在 foo
或 bar
的值更改时收到通知。
一切都适合我,但我仍然遇到这个错误,然后我通过
解决了它
- 在 Identity Inspector 中启用“Inherit module from Target”。
或者
- 从自定义 Class
下的身份检查器中提供模块(通常是文件夹 name/group 名称)
我以前没用过Swift4,也不知道里面怎么用KVC。
我尝试用字典创建模型,这里是代码:
class Person : NSObject {
var name: String = ""
var age: Int = 0
init(dict: [String : Any]) {
super.init()
self.setValuesForKeys(dict)
}
}
let dict: [String : Any] = ["name" : "Leon", "age" : 18]
let p = Person(dict: dict)
print(p.name, p.age)
我有两个问题:
1. 为什么我不用AnyObject
? "Leon"
和18
被推断为String
和Int
,它在KVC中使用吗?
2. @objc var name: String = ""
这个表格可以用,但是看不懂
感谢大家的帮助。
您的代码
var name: String = "" var age: Int = 0
当你确定它的类型时,你可以像这样编写相同的代码。
var name = "" var age = 0
Any一般用于所有类型(函数类型和可选类型),而AnyObject用于Class类型。
@objc 有不同的含义,当您在 swift class 中使用 @objc 时,该代码在 objective-c 中可用。您应该使用@objc 属性来指定与 objective-c class 相同的结果,旧的存档可以被新的 swift class.
[=27= 替换]
要在 Swift 4 中实现对 属性 的 KVC 支持,您需要做两件事:
由于目前的KVC实现是在Objective-C中写的,你需要在你的属性上加上
@objc
注解,这样Objective-C才能看到它。这也意味着 属性 的类型需要与 Objective-C. 兼容
除了将 属性 公开给 Objective-C 之外,您还需要设置通知,以便在 属性 更改时通知观察者.有以下三种方法:
对于存储属性,最简单的做法是添加 dynamic
关键字,如下所示:
@objc dynamic var foo: String
这将允许 Cocoa 使用 Objective-C 魔法自动为您生成所需的通知,这通常是您想要的。但是,如果需要更精细的控制,也可以手动编写通知代码:
@objc private static let automaticallyNotifiesObserversOfFoo = false
@objc var foo: String {
willSet { self.willChangeValue(for: \.foo) }
didSet { self.didChangeValue(for: \.foo) }
}
automaticallyNotifiesObserversOf<property name>
属性 是为了向 KVC/KVO 系统表明我们正在自己处理通知,Cocoa 不应该尝试为其生成通知我们
最后,如果你的 属性 没有被存储,而是依赖于其他一些 属性 或属性,你需要像这样实现一个 keyPathsForValuesAffecting<your property name here>
方法:
@objc dynamic var foo: Int
@objc dynamic var bar: Int
@objc private static let keyPathsForValuesAffectingBaz: Set<String> = [
#keyPath(foo), #keyPath(bar)
]
@objc var baz: Int { return self.foo + self.bar }
在上面的示例中,baz
属性 的观察者将在 foo
或 bar
的值更改时收到通知。
一切都适合我,但我仍然遇到这个错误,然后我通过
解决了它- 在 Identity Inspector 中启用“Inherit module from Target”。 或者
- 从自定义 Class 下的身份检查器中提供模块(通常是文件夹 name/group 名称)