【问题标题】:How do I use Key-Value Coding in Swfit 4.0?如何在 Swift 4.0 中使用键值编码?
【发布时间】:2018-05-21 08:37:03
【问题描述】:

之前没用过Swift4,也不知道怎么用KVC。
我尝试用 Dictionary 创建模型,这里是代码:

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"and18 被推断为 StringInt,它在 KVC 中使用吗?
2.@objc var name: String = "",这个表格可以用,但是看不懂。

感谢所有帮助。

【问题讨论】:

  • 再次阅读您的代码,它显示“keys”的设置值现在“AnyObject”中的键在哪里。我也不明白问题的第二部分
  • 以上代码错误。 XCode 将因未捕获的异常而崩溃。如果使用@objc,它将起作用。我不明白它是如何工作的。
  • 下次提问前请先搜索。我花了 10 秒钟才找到关于What is @objc的答案
  • 对不起,这是我第一次使用 StackOverFlow...

标签: ios swift xcode9 kvc


【解决方案1】:
  1. 你的代码

    var name: String = "" var age: Int = 0

    当你确定它的类型时,你可以像这样编写相同的代码。

    var name = "" var age = 0

    Any一般用于所有类型(函数类型和可选类型),而AnyObject用于Class类型。

  2. @objc 有不同的含义,当您在 swift 类中使用 @objc 时,该代码在 Objective-c 中可用。您应该使用@objc 属性来指定与objective-c 类相同的属性,结果旧档案可以被新的swift 类替换。

【讨论】:

  • 感谢您的回答。你能告诉我 KVC 通常在 Swift 4.0 中是如何使用的吗?
【解决方案2】:

要在 Swift 4 中实现对属性的 KVC 支持,您需要做两件事:

  1. 由于当前 KVC 的实现是用 Objective-C 编写的,因此您需要在属性上添加 @objc 注释,以便 Objective-C 可以看到它。这也意味着属性的类型需要与 Objective-C 兼容。

  2. 除了将属性暴露给 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 的值发生变化时收到通知。

【讨论】:

  • 感谢您的帮助。我会深入研究它。我可以回答最后一个问题吗?我应该在 Swift 中了解更多关于 KVC 的文档?我不擅长苹果的英文文档……
  • @Ben 这是 Apple 在KVCKVO 上的文档。不幸的是,他们主要关注 Objective-C,因此了解这两种语言如何交互将有助于理解它们。
  • 再次欣赏!!我会在 Cocoa 中研究 Swift,然后再回到 Swift 的特性。谢谢你我的朋友!
【解决方案3】:

一切都适合我,但我仍然收到此错误,然后我解决了它

  • 在 Identity Inspector 中启用“从 Target 继承模块”。 或
  • 从自定义类下的身份检查器中提供模块(通常是文件夹名称/组名称)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 2010-12-24
    • 2018-07-23
    相关资源
    最近更新 更多