如何让我的简单对象符合 Swift 中的 NSManagedObject 和 NSCoding

Posted

技术标签:

【中文标题】如何让我的简单对象符合 Swift 中的 NSManagedObject 和 NSCoding【英文标题】:How do I get my simple object to conform to NSManagedObject and NSCoding in Swift 【发布时间】:2016-07-17 08:29:49 【问题描述】:

我有两个对象要快速存储在 Core Data 中。 List 是一个对象,Item 是另一个对象。

这是 List 类:

import Foundation
import CoreData

class List:NSManagedObject 
    /* Remember, any @NSMananged variables added or changed here 
     needs to be reflected in Model */
    @NSManaged var name:String
    @NSManaged var items: [Item]

这是我对 Item 类造成的混乱:

    import Foundation
import CoreData

class Item:NSManagedObject, NSCoding 
    /* Remember, any @NSMananged variables added or changed here
     needs to be reflected in Model */
    @NSManaged var title:String
    @NSManaged var address:String
    @NSManaged var notes:String
    @NSManaged var quantity:Int32

    func encodeWithCoder(aCoder: NSCoder) 
        aCoder.encodeObject(title, forKey: "title")
        aCoder.encodeObject(address, forKey: "add")
        aCoder.encodeObject(notes, forKey: "notes")
        aCoder.encodeInt32(quantity, forKey: "qty")
    

    override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) 

    

    required init(coder aDecoder: NSCoder) 
        title = aDecoder.decodeObjectForKey("title") as! String
        address = aDecoder.decodeObjectForKey("add") as! String
        notes = aDecoder.decodeObjectForKey("notes") as! String
        quantity = aDecoder.decodeInt32ForKey("qty") 
    

我已经阅读了关于 NSManagedObject、NSObject 和 NSCoding 的苹果文档,它也可能是外语的。

如果我不实现任何功能,它不符合 NSCoding。如果我实现 encodeWithCoder() 并要求 init() 它符合 NSCoding 但它希望我添加另一个 init(entity...) 以符合 NSManagedObject。我不知道如何处理这个函数。

在此先感谢您的帮助。这真的让我很头疼。如果您需要更多信息,我会编辑这篇文章以适应。

【问题讨论】:

你为什么要让它符合NSCoding @Wain 我的印象是它必须符合 NSCoding,所以我可以将它存储在 List 类的 items:[Item] 中。这是错的吗? 是的,这是错误的。如果您设置了核心数据模型,以便列表与项目具有多对一关系,那么将全部为您处理 【参考方案1】:

您无需遵守NSCoding。 Core Data 将存储您在模型中定义的所有属性,无需 NSCoding,您无需实现任何东西即可将内容放入数组中。

但是!!

如果您已将核心数据中的属性设置为transformable,那么这就说明了您的前进方向,您需要实现NSCoding,但它也不能是托管对象。这也是错误的方法,因为您应该在模型中使用关系。

【讨论】:

谢谢韦恩。所以不要把它作为可变形的模型放在模型中(这是我所做的)。如果它不可转换,我将数组类型设置为什么?字符串? 删除属性并改为创建双向关系,然后重新生成模型类 - 您可以将可转换属性用于不能/没有意义的实体。该关系将在代码中显示为一个集合。 现在我真的迷路了。然后我是删除类 List 中的属性还是将其保留在那里?如果我删除它,那么如何将项目与特定列表关联?【参考方案2】:

收拾烂摊子的最简单方法:

删除两个NSManagedObject 子类。 在核心数据模型中设置从ListItem(一对多)的关系以及从ItemList 的反向关系。 重新创建NSManagedObject 子类。

就是这样。现在,Core Data 将为您管理一切。不需要NSCoding

编辑:

要为list 对象获取有序的items 数组,例如按quantity 排序的写入

let items = (list.items.allObjects as! [Item]).sort $0.quantity < $1.quantity 

【讨论】:

感谢您的意见。现在我有一个 NSSet,据我所知是无序的。我如何用它填充 tableviewcells,当一个被选择/删除时,我如何确保它是正确的。 您可以使用特定的排序描述符执行提取,或者您可以使用(list.items.allObjects as! [Item]).sort $0.quantity &lt; $1.quantity ,它返回一个数组并通过quantity 对项目进行排序。我编辑了答案。 谢谢。我可以看到它是如何工作的。我正在修复所有现在损坏的代码以处理新数组。感谢您的帮助。

以上是关于如何让我的简单对象符合 Swift 中的 NSManagedObject 和 NSCoding的主要内容,如果未能解决你的问题,请参考以下文章

对象在 Swift 中不符合 kvc 时的对象通信

如何定义一个Swift协议来强制其采用者自己符合相关类型?

Swift 让我对苹果深恶痛绝!

如何让我的背景图像在 Swift 中永远重复?

如何将 ManagedObjectContext 与线程一起使用

如何让我的 X 按钮删除数组中的特定对象?