Core Data 代码生成器如何决定是否将属性设为可选?

Rob*_*ier 5 xcode core-data swift

我正在 macOS 10.13.6 High Sierra 上使用 Xcode 10 + Swift 4.2。我创建了一个数据模型,并让 Core Data 自动为数据模型实体生成类。在大多数情况下,这按预期工作。但是,我无法弄清楚如何预测生成的类中的某些属性是否将成为Optional类型;它似乎并不取决于相应的属性是否被声明为“可选”(即在属性描述中选中了“可选”复选框)。有人可以帮我弄清楚 Xcode 如何确定是否将类属性设为可选吗?

这是我从我的项目中得出的一个小例子。我只是用虚构的名称替换了项目特定的名称,但其他一切都相同。首先这里是从数据模型中提取的 Foo 实体的描述:

<entity name="Foo" representedClassName="Foo" parentEntity="FooParent" syncable="YES" codeGenerationType="class">
  <attribute name="v1" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
  <attribute name="v2" attributeType="Boolean" usesScalarValueType="YES" syncable="YES"/>
  <attribute name="v3" optional="YES" attributeType="Boolean" usesScalarValueType="YES" syncable="YES"/>
  <attribute name="v4" optional="YES" attributeType="UUID" usesScalarValueType="NO" syncable="YES"/>
  <attribute name="v5" optional="YES" attributeType="String" syncable="YES"/>
  <relationship name="v6" toMany="YES" deletionRule="Nullify" destinationEntity="Bar"
                inverseName="baz" inverseEntity="Bar" syncable="YES"/>
</entity>
Run Code Online (Sandbox Code Playgroud)

如您所见,v1、v2 和 v6 在数据模型中未声明为可选,而 v3、v4 和 v5 声明为可选。这是生成的代码,我在我的项目的 Xcode/DerivedData 文件夹下的 Foo+CoreDataProperties.swift 中找到了它。

extension Foo {
    @nonobjc public class func fetchRequest() -> NSFetchRequest<Foo> {
        return NSFetchRequest<Foo>(entityName: "Foo")
    }

    @NSManaged public var v1: Date?
    @NSManaged public var v2: Bool
    @NSManaged public var v3: Bool
    @NSManaged public var v4: UUID?
    @NSManaged public var v5: String?
    @NSManaged public var v6: NSSet?

}
Run Code Online (Sandbox Code Playgroud)

如您所见,v2 和 v3 不是可选的,而 v1、v4、v5 和 v6 是可选的,这与数据模型中看到的可选/非可选分配不同。

有人可以帮助我理解 Core Data 如何决定生成的类属性应该是可选的还是非可选的?

一方面,我发现自己写v!.something在我希望我可以写的地方,v.something因为v它在数据模型中是非可选的,因此肯定会有一些值存在(假设 Core Data 正在执行非可选属性)。

另一方面,我想为数据模型中可选let v = v { ... }的属性编写代码v,因此可能存在也可能不存在值。Xcode 给了我一个关于该构造的错误,但我不能省略测试——我已经知道某些实例v将不存在。尝试通过写入来解决if v != nil { v! }失败——Xcode 给出了一个关于无法解包非可选值的错误(以及一个关于将非可选值与 nil 进行比较的警告)。

预先感谢您对此的任何了解。

编辑:对于与可选属性相对应的非可选属性的最后一点,我看到我可以省略!和写if v != nil { v }——当然,关于将非可选与 nil 进行比较的警告仍然存在,但错误消失了. 所以这是一种解决方法。

Jef*_*ski 1

Core Data 仍然植根于 Objective-C。所以原语 ( bool, int,float等)将是非可选的,而对象将是可选的。

一些数据可以是对象也可以是基元。例如,某人的年龄可能是 aNSNumber或 a NSInteger。如果您希望此类变量由原语支持,那么您可以选中scalar模型中该属性的框。