使用 XCode 8 中 Core Data 生成的类创建对象数组

Posted

技术标签:

【中文标题】使用 XCode 8 中 Core Data 生成的类创建对象数组【英文标题】:Create an array of objects using the class generated by Core Data in XCode 8 【发布时间】:2016-10-27 20:42:02 【问题描述】:

我对 XCode 8 和 Swift 3 如何管理 Core Data 中的类感到有些困惑。

我创建了一个实体,名为PersonMO(“MO”代表“模型对象”)。我的理解是,在创建此实体后构建我的项目会导致在其他地方创建类定义。

如果我尝试使用该类定义创建对象数组,则会出现错误。

var people:[PersonMO] = [
    PersonMO(age:"24", firstName: "Cassie", isVisited: false, lastName: "Brist", locationCity: "San Francisco", locationState: "CA", notes: "none", phoneNumber: "000-0000", zone: "9")
]

错误是“无法使用“此处列出的参数”类型的参数列表调用类型“PersonMO”的初始化程序”,这是有道理的,因为我从未使用默认值初始化 people 数组。

在 XCode 8 和 Swift 3 之前,我有一个 Person.swift 文件,我在其中初始化了我的值,但现在 XCode 在其他地方创建了该类,如果我尝试在该文件中初始化,我会收到“无效的重新声明'PersonMO'”错误。

如何在 XCode 8 和 Swift 3 中创建硬编码的对象数组?

【问题讨论】:

【参考方案1】:

您的问题与生成的类无关。创建NSManagedObject(假设您已经准备好设置NSPersistentContainer):

var people:[PersonMO] = []
persistentContainer.performBackgroundTask  (moc: NSManagedObjectContext) in     

    //create new MO
    let newPersonMo = PersonMO(context: moc)

    // set attributes  
    newPersonMo.name = "Peter"

    //add it to your array
    people.append(newPersonMo)

    //save 
    do 
        try newPersonMo.managedObjectContext?.save()
     catch                     
        print("failed to save with error: \(error)")
    


独立于您的问题,您可以选择 Xcode 是否以及在您的模型检查器中为您的实体创建什么:

我建议将CodeGen 设置为Class Definition

注意:要使这项工作顺利进行(我假设是 Apple 错误),Module 字段必须为空(“全局命名空间”为浅灰色)。

【讨论】:

太棒了,这正是我要找的@shallowThought!我可能会改为使用 CSV 文件进行预加载,但这对于未来非常有用(我对编程非常陌生,所以我经常对所有部分如何交互完全不知所措)。 【参考方案2】:

ios 10 开始,现在可以使用 NSManagedObject.init(context:) 初始化程序,而不是 init(entity:insertInto:)。这是 Apple 为简化对象创建而创建的扩展。但是你仍然需要使用这个初始化器而不是你自己的。


托管对象的指定初始化器是init(entity:insertInto:)。您不应该使用不同的初始化器来初始化托管对象。

来自 Apple 的文档:

托管对象与实体描述(NSEntityDescription 的实例)相关联,该实体描述提供有关对象的元数据(包括对象表示的实体的名称及其属性和关系的名称),并与托管对象相关联。跟踪对象图变化的对象上下文。正确配置托管对象以与 Core Data 一起使用非常重要。如果直接实例化托管对象,则必须调用指定的初始化程序(init(entity:insertInto:))。

【讨论】:

感谢@Leo 的回复。您是说,为了创建从 Core Data 生成的 PersonMO 类构建的对象数组,我需要使用 init(entity:insertInto:)?鉴于无法从项目导航器访问 PersonMO 类,我应该在哪里执行初始化? 最好使用NSEntityDescription.insertNewObject(forEntityName:into:)。我们所做的是在NSManagedObject 上创建一个类别,它会自动执行此操作(我们的实体名称与类名称相同) - 但我们仍然需要提供一个上下文。我们调用了方法insertNewObjectInto(context:) 自从 Swift3/Xcode8 以来,你不再需要所有这些了 @shallowThought 这甚至意味着什么?语言(Swift 3)和 IDE(Xcode)与框架(Core Data)有什么关系? 对不起,简短。待办事项...因为 iOS10 和 Xcode8 是正确的。您不再需要实体名称、EntityDescription 和所有凌乱的样板文件。我仪式性地烧毁了所有这些扩展、Core Data 堆栈等。可以在这个 WWDC 视频中找到粗略的概述:developer.apple.com/videos/play/wwdc2016/242

以上是关于使用 XCode 8 中 Core Data 生成的类创建对象数组的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Xcode 4 中删除 Core Data 动态生成的方法吗?

iCloud Core Data 在 Xcode 6 / ios 8 SDK 中运行后不可用

无法更改 Core Data Xcode 8.2 中的关系属性

使用 Core Data 获取生成“无法识别的选择器错误”?

Core Data 代码生成导致构建失败

操作简单的 Core Data 对象时崩溃