Swift,核心数据,可选的Integer16和keyPath

时间:2018-02-07 19:03:40

标签: swift core-data

我在CoreData中有一个实体,它有一个Integer 16类型的可选属性。它真的可以是nil而在我的应用程序中我想把它称为Int?类型。作为国际? (或者对于那个问题Int16?)不是一个公认的Objective-C类型,编译器会抛出一些摇摆不定的东西。我想避免使用像NSNumber?.intValue这样的代码,所以我实际上已经为这个属性设置了带有自定义访问器的ManagedObject类型。我的问题涉及通过#keyPath而不是静态字符串来识别属性。在核心数据中,该字段在实体“用户”上被命名为“pin”。这是我的代码:

class User: NSManagedObject {
// MARK: - Properties
static let pinKey = "pin"

@NSManaged internal(set) var name: String
@NSManaged fileprivate var primitivePin: NSNumber?

internal(set) var pin: Int? {
    get {
        willAccessValue(forKey: #keyPath(pin))  // THIS LINE ERRORS
        let value: Int? = primitivePin.map { $0.intValue }
        didAccessValue(forKey: User.pinKey)
        return value
    }
    set {
        willChangeValue(forKey: User.pinKey)
        primitivePin = newValue.map { NSNumber(value: Int16($0)) }
        didChangeValue(forKey: User.pinKey)
    }
}

}

错误的行是我想要实现的,但当然var引脚不是obj-c类型而且编译器抱怨,所以我已经定义了静态常量pinKey,如你所见。 #keyPath感觉就像是正确的方法,并且实体确实有一个名为pin的字段,但在这种情况下,我唯一可以选择使用静态值吗?

2 个答案:

答案 0 :(得分:1)

#keyPath中,您必须指定属性名称。如果您没有名为pin的已定义属性,则会收到错误。在您的情况下,您必须使用#keyPath(User.primitivePin)。我相信这应该有用。

另外,我猜,调用地图在这里是多余的。您可以直接写let value = primitivePin?.intValue等等。

答案 1 :(得分:0)

答案是....使用自定义属性/访问器#keyPath无法使用,因为没有定义的@NSManaged属性 - 正如Maksym指出的那样。但是,您也不能使用已定义的原语,而是使用属性名称作为String,如上面的代码所示(User.pinKey)