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 [重复]