Swift、Core Data、可选的 Integer16 和 keyPath

Posted

技术标签:

【中文标题】Swift、Core Data、可选的 Integer16 和 keyPath【英文标题】:Swift, Core Data, Optional Integer16 and keyPath 【发布时间】:2018-02-07 19:03:40 【问题描述】:

我在 CoreData 中有一个实体,它有一个 Integer 16 类型的可选属性。它可以真正为 nil,在我的应用程序中我想将它称为 Int?类型。作为诠释? (或就此而言 Int16?)不是公认的 Objective-C 类型,编译器会抛出一些不稳定的问题。我想避免在整个过程中使用像 NSNumber?.intValue 这样的代码,所以我实际上已经使用此属性的自定义访问器设置了我的 ManagedObject 类型。我的问题与通过 #keyPath 而不是静态字符串来识别属性有关。在 Core Data 中,该字段在实体“用户”上被命名为“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 pin 不是 obj-c 类型并且编译器会抱怨,所以我已经定义了静态常量 pinKey,如您所见。 #keyPath 感觉是正确的方法,实体确实有一个名为 pin 的字段,但在这种情况下,我唯一可以选择使用静态值吗?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

谢谢,但让我困惑的是,以'name'属性为例,Core Data 在后台为这个@managed 属性创建了一个名为primitiveName 的属性。我仍然会将名称引用为#keyPath(name) 而不是#keyPath(primitiveName)。如果我使用#keyPath(primitivePin),Core Data 是否会以相同的方式将其映射到实体 pin 属性(数据模型中实体上的属性是 pin,而不是 originalPin)?有一些关于这个的东西没有点击,我找不到与这个场景相关的任何合适的信息。 PS:当然,访问器你说得对,我被冲昏了头脑!【参考方案2】:

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

【讨论】:

以上是关于Swift、Core Data、可选的 Integer16 和 keyPath的主要内容,如果未能解决你的问题,请参考以下文章

具有标量类型的 Swift Core Data 可选属性被评估为 0 而不是 NIL [重复]

Swift:如果变量 a 是非可选的,那么为啥变量 b 是可选的? [复制]

Swift5.4 中可选的误报

为啥 Swift 隐式展开可选的“nil”?

如何在 Swift 中比较两个可选的 NSArray

在swift中,为什么UIlabel是可选的?