ios - 序列化包含对核心数据中 NSManagedObjects 的引用的多维数组

标签 ios iphone objective-c core-data nscoding

我有两个实体,ChainStepChain有一个属性steps,可以是Step实体的多维数组,例如:

[
  step,
  step,
  step,
  [
    step,
    step
  ],
  step
]

每个 Step 对象都有一个 content 属性,它是一个字符串。

如果我使用的是关系数据库,我会将该数组存储为 JSON,每个 step 都是特定步骤的 step_id

我如何在 Core Data 中实现类似的东西?我想我需要使 Step 类符合 NSCoding 协议(protocol),但那会是什么样子呢?我如何让它在 Chain.steps 的最终值中只存储与其 id 等效的内容,即对自身的引用?

编辑

下面的评论表明我在 Step 和其他 Step 之间包含一对多关系(我们称之为 nextStep)。然后我会使用这种关系在 Chain 中从一个步骤转到下一个步骤,因此 Chain 实体只需要包含第一个 Step在序列中。这样做的问题是 Step 可能属于多个 Chain,因此它可能并不总是具有相同的 nextStep 值。

最佳答案

我不希望您对包含 Core Data 对象的数组进行序列化和反序列化。您可以转换数组以保存步骤的对象 ID 的 URIRepresentation,但是如果从数据库中删除步骤会怎样?您的序列化数组仍然被旧对象污染。


这是我的建议。

https://github.com/LeoNatan/ChainStepsExample

我的模型是这样设置的:

Model

Link 是一个抽象实体。

为了方便使用,我定义了如下协议(protocol):

@protocol Link <NSObject>

//This is to make chain traversal easy - all links are guaranteed to have "steps".
- (NSOrderedSet*)steps;

@end

为了创建,我添加了以下方便的工厂方法:

@interface Link : NSManagedObject <Link>

+ (id<Link>)linkWithStepsArray:(NSArray*)stepsArray inContext:(NSManagedObjectContext*)context;
+ (id<Link>)linkWithStepsOrderedSet:(NSOrderedSet*)stepsOrderedSet inContext:(NSManagedObjectContext*)context;
+ (id<Link>)linkWithStep:(Step*)step inContext:(NSManagedObjectContext*)context;

@end

现在,链的创建和遍历非常容易。

Step* step1 = [Step newObjectInContext:context];
step1.content = @"Wake up";

Step* step2_1 = [Step newObjectInContext:context];
step2_1.content = @"Go to school";

Step* step2_2 = [Step newObjectInContext:context];
step2_2.content = @"Learn new things";

Step* step3 = [Step newObjectInContext:context];
step3.content = @"Go to sleep";

NSOrderedSet* links = [NSOrderedSet orderedSetWithObjects:[Link linkWithStep:step1 inContext:context], [Link linkWithStepsArray:@[step2_1, step2_2] inContext:context], [Link linkWithStep:step3 inContext:context], nil];
[chain setLinks:links];

最后遍历:

for(Chain* chain in chains)
{
    NSLog(@"<chain %@>", chain.name);

    for(id<Link> link in chain.links)
    {
        NSLog(@"\t<step>");
        for(Step* step in link.steps)
        {
            NSLog(@"\t\t%@", step.content);
        }
        NSLog(@"\t</step>");
    }

    NSLog(@"</chain>\n\n");
}

这为您提供了一个可管理的对象图,它将在删除任务时自动重建。

这是一个简单的例子。它只解决了一个层次的问题。您可以在 SingleStepLinkMultiStepLinkLink(而不是 Step)之间建立一个无限深度的关系,叶子与 Step 有最终关系。

关于ios - 序列化包含对核心数据中 NSManagedObjects 的引用的多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22283836/

相关文章:

iOS Swift 从推送通知以编程方式导航到某些 ViewController

ios - 根据控制台,委托(delegate)似乎没有工作

iphone - 选项卡栏图标选定的图像

objective-c - 如何按字母顺序对 NSArray 进行排序?

iOS 模拟器在屏幕的 3/4 处显示黑色

ios - 下载多个视频和音频

objective-c - 可用于设置计算机 sleep 并在 mac os x 中的 cocoa 应用程序中显示 sleep 值的 API

ios - 页面消失时删除长时间运行的动画

iphone - 递归地将 self.view 添加到 self.view 中?

ios - iOS 11 中的 NSFoundationVersionNumber - 如何以编程方式检测 iOS 版本