核心数据 - 将实体保存为 pList / 字典

Posted

技术标签:

【中文标题】核心数据 - 将实体保存为 pList / 字典【英文标题】:Core Data - Saving an Entity as a pList / dictionary 【发布时间】:2012-10-06 11:08:22 【问题描述】:

我有一个非常简单的应用程序,它有一个与自身具有循环关系的 CoreData 实体。我想将此数据用作另一个应用程序中的 plist。

这种关系在父方是“对一个”,在子方是“对多”。

基本上是一棵树,顶部有一个项目,然后是该对象的子对象,子对象的子对象,等等......

我想从这些数据中创建一个字典/pList,其中包含实体的结构,包括关系。 (这有意义吗?)

到目前为止,在此处其他答案的帮助下,我可以获得所有对象的 plist(但都在同一“级别”上)或最终父对象的 plist(但子关系有问题)。

这就是我正在做的尝试获取数据并将其保存到我的桌面:

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_NAME];
    request.resultType = NSDictionaryResultType;

    NSError *fetchError = nil;
    NSArray *results = [self.databaseDocument.managedObjectContext executeFetchRequest:request error:&fetchError];

    NSLog(@"%@", results);

    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [caches stringByAppendingPathComponent:@"/../../../../../../../../Desktop/my.plist"];
    [results writeToFile:path atomically:NO];

目前只有三个对象。主对象、该对象的子对象以及该子对象的子对象。

这给了我一个 plist,它是一个包含三个对象的数组。

如果我包含一个谓词以仅获取没有父对象的对象,如下所示:

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_NAME];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"parent == nil"];
    request.predicate = predicate;

    NSError *fetchError = nil;
    NSArray *results = [self.databaseDocument.managedObjectContext executeFetchRequest:request error:&fetchError];

    NSLog(@"%@", results);

    Item *mainItem = [results lastObject];

    NSArray *keys = [[[mainItem entity] attributesByName] allKeys];
    NSDictionary *dict = [mainItem dictionaryWithValuesForKeys:keys];

    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [caches stringByAppendingPathComponent:@"/../../../../../../../../Desktop/my.plist"];
    [dict writeToFile:path atomically:NO];

这给了我一个目录,但不包括孩子。

谁能向我解释如何让 plist 像我的实体一样结构化?换句话说,只有一个目录,其中包含所有子项,以及该子项的目录中每个子项的子项,依此类推...?

【问题讨论】:

父子关系中的递归是否有任意深度? @NSBum 是的,它可以永远持续下去。 @NSBum 但实际上最多只有大约 6 或 7 个级别 【参考方案1】:

可能有更好的方法将您的核心数据实体导出到 plist,同时保留关系的层次结构 - 我愿意接受教育。我会用这样的递归方法处理它们:(这完全未经测试 - 仅用于说明目的 - 我也不完全确定您希望 plist 的结构方式等)

- (void)processEntity:(NSManagedObject *)object forMutableArray:(NSMutableArray *)mutableArray 
    NSMutableDictionary *entityInfo = [NSMutableDictionary new];

    // populate entityInfo with your object's properties
    // however you are doing that now...


    //  if this object has children - process them
    NSMutableArray *childArray = [NSMutableArray new];
    for( id child in object.children ) 
        [self processEntity:child forMutableArray:childArray];
    

    [entityInfo setObject:childArray forKey:@"children"];
    [mutableArray addObject:entityInfo];

因此,您通过迭代***对象(没有父对象的对象)开始该过程,然后在 processEntity:forMutableArray: 中处理它们

【讨论】:

我不得不出去,所以还不能尝试这个,但是当我回到计算机上时,我会回复你。我认为可能有一种方法可以在不出错的情况下获取***对象,并且这会自动填充我的 plist。我对核心数据非常陌生。 很有魅力!感谢您的帮助,也很快。我打算接下来开始这条路,但这真的非常有帮助。我可能需要很长时间才能将其缩小到这一点。

以上是关于核心数据 - 将实体保存为 pList / 字典的主要内容,如果未能解决你的问题,请参考以下文章

使用 plist 将数据插入核心数据时卡住

如何按名称从 plist 中提取数据?

核心数据、字典还是 plist?

将 plist 加载到核心数据中

搜索核心数据与 Plist

最佳实践? - 数组/字典作为核心数据实体属性 [关闭]