如何使用committedValuesForKeys来保存和重构NSManagedObjects?

时间:2016-02-07 15:27:53

标签: swift core-data nsmanagedobject cloudkit

Nota Bene

  

如果需要更多信息,请在评论中提供建议。

背景

仅使用Apple API我感兴趣的是将NSManagedObject或对象图中的数据保存到文件中,以便我可以将其作为资产保存在CloudKit中,并通过公共数据库在用户之间共享。关于SO的几个问题解决了持续NSManagedObject的问题。没有人给出适合我的用例的答案。

理论

我在Apple的文档中注意到以下条目。由于自iOS 3.0以来已经可以使用,我想知道其他人是否已经使用它,以及结果字典是否是一个合适的解决方案,用于保存我想通过网络发送的数据。我的想法很简单,字典可以存档或写入文件并作为CKAsset上传。然后可以将下载的资产解压缩到字典中,该字典还应该允许人们为新的核心数据上下文重建新的NSManagedObject

committedValuesForKeys

调试代码

所以,当然认为这是可能的,我跳进去开始使用字典。这段代码试图帮助我理解在这样一个字典中可以期待的值的性质以及如何使用这些值来重新创建一个新对象。

func debugEncodeObject () {
    if let aManagedObject = self.videoStory {
        if let uncodedObject = aManagedObject.committedValuesForKeys(nil) as? NSDictionary {


            for (key, value) in uncodedObject {
                print("key:\(key)\nvalue:\(value)\ndynamictype:\(value.dynamicType)\ndescription:\(value.description)")
            }
//            let tmpPath = NSTemporaryDirectory().NS.stringByAppendingPathComponent("MNG-\(NSUUID().UUIDString)")
//                print(tmpPath)
//                
//                if uncodedObject.writeToURL(NSURL(fileURLWithPath: tmpPath), atomically: true) {
//                    print(uncodedObject)
//                    MNGCloudManager.sharedInstance.insertSharedStoryRecord(uncodedObject)
//                    
//                }
        }
    }
}

并发症

因此,查看我的检查代码的结果,我可以看到我的字典中有几个非标准条目。一些更有趣的结果显示了一些引起赌注的并发症。例如,查看存储在字典中的NSOrderedSet的值显示对象的内存(指针?)表示,包括子对象的表示。我也看到了子对象的单独表示,所以我认为我应该能够用现有数据重建新对象。

key:videos

value:Relationship 'videos' on managed object (0x1467b9750) <ths.VideoStory: 0x1467b9750> (entity: VideoStory; id: 0xd000000000380002 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/VideoStory/p14> ; data: {

    assetURL = nil;

    authoredBy = nil;

    collageImage = <ffd8ffe0 00104a46 49460001 01000000 00000000 ffe10080 45786966 00004d4d 002a0000 00080005 01120003 00000001 0001>;

    comments = Story;

    externalGUID = nil;

    externalURL = nil;

    lastModified = nil;

    location = nil;

    metadata = nil;

    ratingsArray = nil;

    sharable = 0;

    sharedWith =     (

    );

    summary = "A saga to tell. ";

    tagCount = 0;

    tagsArray = nil;

    timeStamp = "2015-12-24 19:29:46 +0000";

    title = Story;

    tokens =     (

    );

    videos =     (

        "0xd0000000006c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p27>",

        "0xd0000000004c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p19>"

    );

}) with objects {(

    <ths.Video: 0x1467ef540> (entity: Video; id: 0xd0000000006c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p27> ; data: {

    author = nil;

    comment = nil;

    location = nil;

    tagsArray = nil;

    thumbnail = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe1004c 45786966 00004d4d 002a0000 00080002 01120003 00000001 0001>;

    timeStamp = "2016-01-25 17:21:28 +0000";

    videoFile = "0xd0000000006c0006 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/VideoFile/p27>";

    videoStories = "<relationship fault: 0x1479305c0 'videoStories'>";

}),

    <ths.Video: 0x1467f63a0> (entity: Video; id: 0xd0000000004c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p19> ; data: <fault>)

)}

dynamictype:_NSFaultingMutableOrderedSet

description:Relationship 'videos' on managed object (0x1467b9750) <ths.VideoStory: 0x1467b9750> (entity: VideoStory; id: 0xd000000000380002 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/VideoStory/p14> ; data: {

    assetURL = nil;

    authoredBy = nil;

    collageImage = <ffd8ffe0 00104a46 49460001 01000000 00000000 ffe10080 45786966 00004d4d 002a0000 00080005 01120003 00000001 0001>;

    comments = Story;

    externalGUID = nil;

    externalURL = nil;

    lastModified = nil;

    location = nil;

    metadata = nil;

    ratingsArray = nil;

    sharable = 0;

    sharedWith =     (

    );

    summary = "A saga to tell. ";

    tagCount = 0;

    tagsArray = nil;

    timeStamp = "2015-12-24 19:29:46 +0000";

    title = Story;

    tokens =     (

    );

    videos =     (

        "0xd0000000006c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p27>",

        "0xd0000000004c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p19>"

    );

}) with objects {(

    <ths.Video: 0x1467ef540> (entity: Video; id: 0xd0000000006c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p27> ; data: {

    author = nil;

    comment = nil;

    location = nil;

    tagsArray = nil;

    thumbnail = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe1004c 45786966 00004d4d 002a0000 00080002 01120003 00000001 0001>;

    timeStamp = "2016-01-25 17:21:28 +0000";

    videoFile = "0xd0000000006c0006 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/VideoFile/p27>";

    videoStories = "<relationship fault: 0x1479305c0 'videoStories'>";

}),

    <ths.Video: 0x1467f63a0> (entity: Video; id: 0xd0000000004c0004 <x-coredata://C26A39CE-7016-48EE-9228-9B6B39E94BFB/Video/p19> ; data: <fault>)

)}

问题

在重新发明轮子之前,我是否遗漏了一些关于这本词典的性质和用途的明显内容?就像一个内置的API,可以做我想要的(使用字典构建并将匹配的新托管对象图插入到不同手机上的不同上下文中)?此外,这个字典NSValue中的值是多少?如果是这样,我可能需要将它们作为对象存储在新词典中。 Apple提供此信息以便轻松将NSManagedObject分拆为NSDictionary。我错过了反向的功能吗?

其他想法

我确实理解NSManagedObject s最初设计为仅存在于上下文中。然而,自iOS 3.0以来,API方法一直存在,所以人们认为它有一些有用的用途。我需要创建最保守的内存使用操作。有这方面经验的人是否可以分享对这种方法的担忧或建议替代方案?

1 个答案:

答案 0 :(得分:0)

使用KVC。

对于NSManagedObject的属性,请使用:

NSArray *keys = [[[object entity] attributesByName] allKeys];
NSDictionary *dictionary = [object dictionaryWithValuesForKeys:keys];

生成的字典将使用模型中定义的标准类型的值。要将此类字典中的值恢复为实例化的NSManagedObject

[object setValuesForKeysWithDictionary:dictionary];

对于关系,有relationshipsByName。通过调用dictionaryWithValuesForKeys:,您将获得字典,其值为NSManagedObject类型为to-one,并且根据您的模型,为多对多关系的有序或无序集合,每个包含{{1} }秒。你必须迭代它们并同样获得它的属性。