如何使用 swift 4.2 学习 KVC



我正在使用带有swift 4.2的Xcode 10.0来学习"Cocoa programming for OSX"中的键值编码

我被要求创建一个简单的类,它是 NSObject 的一个子类。以下代码:

import Cocoa
class Student: NSObject {
var name: String = ""
var gradeLevel: Int = 0
}
let student1 = Student()

student1.setValue("Benny", forKeyPath: "name")

student1.setValue("Benny", forKeyPath: "name"(

生成以下错误消息:

执行中断,原因:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0(。

我在网上看过,似乎有一些关于KVC的问题,例如: https://bugs.swift.org/browse/SR-5139

我做错了什么?该书于2015年出版。

在 Swift 4 中,出于性能原因,不再推断向 Objective-C 运行时公开代码。
为避免崩溃,您必须显式添加@objc属性。

@objc var name: String = ""

但是从 Swift 的强类型的角度来看,有两种更好的方法来使用 KVC 获取值:

  1. #keyPath指令也使用 ObjC 运行时,但在编译时检查键路径

    let keyPath = #keyPath(Student.name)
    student1.setValue("Benny", forKeyPath: keyPath)
    

    在这种情况下,您会收到一个非常描述性的编译器警告

    "#keyPath"的参数是指"学生"中的属性"名称",它依赖于 Swift 4 中弃用的"@objc"推理

  2. (推荐的(原生方式:Swift 4+ 提供了自己的 KVC 模式,不需要子类化NSObject
    键路径由前导反斜杠指示,后跟类型和属性(或属性(:

    class Student {
    var name: String = ""
    var gradeLevel: Int = 0
    }
    let student1 = Student()
    student1[keyPath: Student.name] = "Benny"
    

KVC的简单示例

在这里,我们直接通过实例访问 SimpleClass 的 name 属性。

class SimpleClass {
var name: String
init(name: String) {
self.name = name
}
}
let instance = SimpleClass(name: "Mike")
let name = instance.name
print("name: (name)")

但是在KVC中,我们通过forKey访问类的name属性。

class KVCClass: NSObject {
@objc dynamic var name: String
init(name: String) {
self.name = name
}
}
let instance = KVCClass(name: "Mike")
if let name = instance.value(forKey: "name") as? String {
print("name: (name)")
}

最新更新