【问题标题】:Create an array of objects using the class generated by Core Data in XCode 8使用 XCode 8 中 Core Data 生成的类创建对象数组
【发布时间】: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 中创建硬编码的对象数组?

【问题讨论】:

    标签: arrays core-data swift3 xcode8


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 2020-02-04
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    相关资源
    最近更新 更多