4

我想将我的参考数据与我的核心数据模型中的用户数据分开,以简化我的应用程序的未来更新(因为,我计划将数据库存储在云上,并且不需要将参考数据存储在云上这是我的应用程序的一部分)。因此,我一直在寻找一种使用获取的属性对跨商店关系进行编码的方法。我还没有找到任何示例实现。

我有一个使用 2 种配置的核心数据模型:

  • 数据模型配置 1:UserData(相对于用户的实体)

  • 数据模型配置 2:ReferenceData(相对于应用程序本身的实体)

我为这两个配置设置了 2 个不同的 SQLite 持久存储。

  • UserData 配置(和存储)包含实体“用户”

  • ReferenceData 配置(和存储)包含实体“类型”和“项目”。

我想创建两个单向弱关系,如下所示:

  • “用户”具有唯一的“类型”

  • 一个“用户”有许多“项目”

这是我的问题:

  • 如何设置我的属性?

  • 每个关系是否需要 2 个属性(一个用于存储唯一 ID,另一个用于访问我获取的结果)?

  • 这种微弱的关系能否有序?

  • 有人可以给我一个示例实现吗?

作为马库斯回答的后续:

浏览论坛和文档,我读到我应该使用我的实体实例的 URI 表示而不是 objectID。这背后的原因是什么?

// Get the URI of my object to reference 
NSURL * uriObjectB [[myObjectB objectID] URIRepresentation];

接下来,我想知道,如何将我的对象 B URI (NSURL) 作为弱关系存储在我的父对象 A 中?我应该使用什么属性类型?我该如何转换?我听说存档...?

然后,稍后我应该以相同的方式检索托管对象(通过取消转换/取消归档 URIRepresentation)并从 URI 获取对象

// Get the Object ID from the URI 
NSManagedObjectID* idObjectB = [storeCoordinator managedObjectIDForURIRepresentation:[[myManagedObject objectID] URIRepresentation]];

// Get the Managed Object for the idOjectB ...

最后但同样重要的是,我是否应该在我的实体 A 中声明两个属性,一个用于保持 URI 需求,另一个用于检索直接对象 B?

NSURL * uriObjectB [objectA uriObjectB];

ObjectB * myObjectB = [objectA objectB];

正如你所读到的,我真的很想念一些简单的例子来实现这些弱关系!我真的很感激一些帮助。

4

2 回答 2

6

到目前为止,拆分数据是正确的答案。参考数据不应与云同步,特别是因为 iCloud 对允许应用程序同步和存储在文档中的内容有软上限。

要创建对商店的软引用(它们不需要是 SQLite,但对于一般应用程序性能来说这是一个好主意),您需要有某种可以从另一端引用的唯一键;一个很好的老式外键。

从那里你可以在模型中创建一个获取的属性来引用实体。

虽然这种关系不能直接排序,但您可以通过排序索引创建排序,或者如果它具有逻辑排序,那么您可以在检索数据后对其进行排序(我为此使用返回排序数组而不是集合的便捷方法)。

我可以建立一个例子,但你真的走在正确的轨道上。唯一有趣的部分是迁移。当您检测到迁移情况时,您需要在构建核心数据堆栈之前独立迁移每个存储。这听起来很棘手,但实际上并不难完成。

例子

假设您在用户存储中有一个 UserBar 实体,在参考存储中有一个 RefBar 实体。然后 RefBar 将与 UserBar 具有 fetchedProperty “关系”,从而创建 ToOne 关系。

UserBar
----------
refBarID : NSInteger

RefBar
--------
identifier : NSInteger

然后,您可以使用以下谓词在建模器中的 RefBar 实体上创建一个获取的属性:

$FETCHED_PROPERTY.refBarID == 标识符

让我们命名谓词“userBarFetched”

现在这将返回一个数组,所以我们想为 RefBar 添加一个方便的方法

@class UserBar;

@interface RefBar : NSManagedObject

- (UserBar*)userBar;

@end

@implementation RefBar

- (UserBar*)userBar
{
    NSArray *fetched = [self valueForKey:@"userBarFetched"];
    return [fetched lastObject];
}

@end

创建 ToMany 是相同的,只是您的便捷方法将返回一个数组,并且您将在返回之前对数组进行排序。

正如Heath Borders所提到的,如果您愿意,可以在其中添加一种排序,NSFetchedProperty但您必须在代码中进行。就我个人而言,我一直觉得它很浪费,并且不使用该功能。如果我可以在建模器中设置排序可能会更有用。

使用对象 ID

我不建议使用 ObjectID 或 URIRepresentation。ObjectID(以及该 ObjectID 的 URIRepresentation)可以并且将会改变。每当您迁移数据库时,该值都会发生变化。您最好创建一个不变的 GUID。

弱关系

您只需要关系的 M 侧的单个值并存储外部标识符。在您的对象子类中,您只需要实现检索对象(或对象)的访问器。

于 2011-11-21T19:56:05.440 回答
-2

我只会去一家商店。

为了在云中存储内容,无论如何您都必须将数据序列化为 JSON 或 SQL 语句,或者您喜欢的任何方案。

您将需要用户设备上数据的本地副本,以便他可以快速离线访问它。云存储可以只有用户实体,而本地存储(应用程序的一部分)也可以有引用实体。

我有一个类似的项目,其中包含一个巨大的参考存储(20000 条记录),其中包含地理信息和用户生成的内容(“帖子”)。我使用一个商店。当我发布应用程序时,“帖子”实体也已定义但为空。当我更新数据模型时,我只是在发货前重新生成整个参考存储。

我认为绝对没有理由在这里寻求跨店解决方案。

于 2011-11-21T16:40:10.787 回答