【问题标题】:What the difference between setValue and myObject.propertyName in iOS Swift 3.1?iOS Swift 3.1 中的 setValue 和 myObject.propertyName 有什么区别?
【发布时间】:2017-05-22 09:17:41
【问题描述】:

我有这样的对象:

class Human: NSObject {
    var name:String!
    var age:Int!
}

然后像这样从对象中创建实例:

let instance = Human()  

并像这样设置我的值:

instance.name = "Kirk"
instance.age = 87

然后像这样打印出来:

print("name: \(instance.name)") // Kirk
print("age: \(instance.age)") //87

一切正常。但现在以另一种方式设置我的值:

instance.setValue("Kirk", forKey: "name")
instance.setValue(87, forKey: "age")

Int 数据类型出现此错误:

*** 由于未捕获的异常 'NSUnknownKeyException' 导致应用程序终止,原因:'[ setValue:forUndefinedKey:]: this 类不符合键年龄的键值编码。

为什么会这样?
以及如何解决这个问题,因为我需要使用 setValue() 函数。

【问题讨论】:

  • 区别在于instance.name是通过原生Swift机制访问属性,而instance.setValue("Kirk", forKey: "name")需要键值编码(KVC),只有当类型可以在Objective-C中表示时才有效.正如其他人指出的那样,Int! 不能在 Objective-C 中表示,因此它不能参与 KVC。将ageInt! 更改为IntNSNumber!,它将正常工作。 (很明显,如果将其更改为Int,则需要确保将其初始化为非nil 值,大概是使用将值作为参数的init 方法。)

标签: ios swift int key-value-coding


【解决方案1】:

键值编码 (KVC) 依赖于 Objective-C 功能,Int! 类型在技术上是可选的值类型。可选值类型不能在 Objective-C 中表示,这就是调用失败的原因。

如果你添加一个显式的dynamic 属性,你会看到编译错误:

class Human: NSObject {
    var name:String!   
    dynamic var age: Int!
}

它适用于Int

在这种情况下使用隐式展开的选项无论如何都是一个坏主意。您应该将这些属性设置为非可选,并在初始化程序中对其进行初始化。

【讨论】:

  • 一些可选值类型(例如String!)可以在Obj-C中表示——Int只是有问题,因为它被桥接到NSInteger,因此无法表示@ 987654328@.
  • @Hamish 确实,桥接对象是引用类型(Data、数组、字典等)有明显的例外。
【解决方案2】:

Int! 不能像其他提到的那样表示为 int Objective-C。这应该工作

class Human: NSObject {
    var name:String!
    var age : Int;

    init(name:String?, age:Int) {
        self.age = age
        self.name = name
    }
}

【讨论】:

  • 按照@Rob 的建议更新
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2018-02-14
  • 2015-12-02
  • 1970-01-01
  • 1970-01-01
  • 2017-03-03
  • 2018-03-21
  • 2015-02-10
相关资源
最近更新 更多