将数据存储在核心数据的自定义类数组中 [英] Store data in custom class array in core data

查看:90
本文介绍了将数据存储在核心数据的自定义类数组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实体,在该实体中有一些属性,我已将自定义类传递给该属性,这些自定义类将数据存储在该类的数组中
我的核心数据实体看起来像这样,

I have an entity in which i have some attributes to which I have pass custom class which store data in an array of that class My core data entity looks like this,

我的 NSManangedObject 类看起来像这样,

extension SingleChat {

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

    @NSManaged public var name: String?
    @NSManaged public var roomSID: String?
    @NSManaged public var isGroup: Bool
    @NSManaged public var lastMessage: String?
    @NSManaged public var lastMsgTime: String?
    @NSManaged public var lastMsgTimeActual: String?
    @NSManaged public var profilePic: String?
    @NSManaged public var lastMsgRead: Bool
    @NSManaged public var unReadMsgsCount: Int16
    @NSManaged public var actualNameFor_1_2_1_chat: String?
    @NSManaged public var isNewGroup: Bool
    @NSManaged public var members : [TCHMember]
    @NSManaged public var messages : [TCHMessage]
    @NSManaged public var twChannelObj: TCHChannel?
    @NSManaged public var groupInfo : [String:JSON]?
}

这就是我将数据保存在核心数据中的方式,

This is how i save my data in core data ,

 let appDelegate = UIApplication.shared.delegate as? AppDelegate
        let context = appDelegate?.persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "SingleChat", in: context!)
        let user = NSManagedObject(entity: entity!, insertInto: context)

        for items in dateWiseSortedSingleRooms
        {
            user.setValue(items.name, forKey: "name")
            user.setValue(items.actualNameFor_1_2_1_chat, forKey: "actualNameFor_1_2_1_chat")
            user.setValue(items.isGroup, forKey: "isGroup")
            user.setValue(items.lastMsgRead, forKey: "lastMsgRead")
            user.setValue(items.lastMsgTimeActual, forKey: "lastMsgTimeActual")
            user.setValue(items.lastMessage, forKey: "lastMessage")
            user.setValue(items.lastMsgTime, forKey: "lastMsgTime")
            user.setValue(items.profilePic, forKey: "profilePic")
            user.setValue(items.roomSID, forKey: "roomSID")
            user.setValue(items.isNewGroup, forKey: "isNewGroup")
            user.setValue(items.unReadMsgsCount, forKey: "unReadMsgsCount")
            user.setValue(items.unReadMsgsCount, forKey: "unReadMsgsCount")
            user.setValue(items.members, forKey: "members")
            user.setValue(items.messages, forKey: "messages")
            user.setValue(items.twChannelObj, forKey: "twChannelObj")
        }

        do {
            try context?.save()
            print("Saved successfully.")
        } catch  {
            print("Fail to save")
        }

现在执行我的代码时应用程序在此行崩溃

Now when my code execute app crashes at this line,

user.setValue(items.members, forKey: "members")
user.setValue(items.messages, forKey: "messages")

有错误,


由于未捕获的异常而终止应用程序
'NSInvalidArg umentException',原因:'-[TCHMember encodeWithCoder:]:
无法识别的选择器发送到实例0x2807a1780

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TCHMember encodeWithCoder:]: unrecognized selector sent to instance 0x2807a1780

我该如何解决这个?并在其中存储我的自定义类数组数据?

How I can resolve this? and store my custom class array data in it?

推荐答案

如果要在核心数据中存储非标准对象,则相应属性的类型为 transformable ,因此可以将其转换为 NSData 并返回。

如果对象采用需要实现功能的 NSCoding协议,则可以执行此操作 encode(with:) init(coder:)(此处有描述)。这些函数定义了必须存储和还原自定义对象的哪些属性。

有关如何使用这些函数的示例,请参见此处

If you want to store non-standard objects in core data, the corresponding attribute is of type transformable, so that it can be converted to NSData and back.
This can be done if the object adopts the NSCoding protocol, which requires to implement the functions encode(with:) and init(coder:) (described there). These functions define which properties of your custom object have to be stored and restored.
An example how to use these functions can be found here.

编辑:

还有另一种处理可转换属性的方法:代替采用 NSCoding 协议,则可以实现自定义 NSValueTransformer 。该类可以独立于您的第三方类实现,请参见此处,并在您的核心数据模型中指定请参见此处。可以在此处找到示例。

There is another way to handle transformable attributes: Instead of adopting the NSCoding protocol, you could implement your custom NSValueTransformer. This class can be implemented independently of your 3rd party classes, see here, and is specified in your core data model, see here. An example can be found here.

编辑2:

我自己没有使用第二种方法,但是我的印象是:

为了将自定义对象存储在核心数据中,必须将其转换为 NSData ,并在获取过程中将 NSData 必须转换回您的对象。

I did not use the 2nd method by myself, but my impression is:
In oder to store a custom object in core data, it must be converted to NSData, and during a fetch NSData must be converted back to your object.

一种方法是使用 NSCoding ,但这需要在自定义类中实现,也许作为扩展。如果您无法做到这一点,则可以实现自定义 NSValueTransformer 对象。

One way to do so is to use NSCoding, but this requires to implement it in the custom class, maybe as an extension. If this is not possible, as in your case, you can implement a custom NSValueTransformer object.

要进行编码,系统会为您提供一个自定义对象作为输入,并根据需要创建一个 NSData 对象相关属性。为了进行解码,它接受 NSData 对象,并初始化自定义对象的新实例,并设置这些属性。

For encoding, it is given one of your custom objects as input, and creates as appropriate an NSData object from the relevant properties. For decoding, it accepts a NSData object, and initialises a new instance of your custom object, and sets these properties.

您只需在核心数据模型中指定 NSValueTransformer 的名称,核心数据便会使用此名称自定义 NSValueTransformer 。您可以在此处找到示例

You just have to specify the name of the NSValueTransformer in your core data model, and core data will use this custom NSValueTransformer. You can find an example here.

这篇关于将数据存储在核心数据的自定义类数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆