【问题标题】:Best practice for temporary objects in RestKit with Core DataRestKit 中使用 Core Data 的临时对象的最佳实践
【发布时间】:2012-04-11 09:47:50
【问题描述】:

背景:我有一个托管对象 Car。我在 localhost/cars/search 上有一个 RESTful 搜索 API。返回的结果是来自服务器端的 Car 对象,但我只想保存用户选择的对象。我想在他们退出搜索时丢弃的其余汽车。

一开始我都是这样的:

@interface Car : NSManagedObject  //<--- managed object

    @property (nonatomic, strong) NSNumber* year;
    @property (nonatomic, strong) NSString* make;
    @property (nonatomic, strong) NSString* model;

@end

@interface TransientCar : NSObject //<--- regular NSObject!

    @property (nonatomic, strong) NSNumber* year;
    @property (nonatomic, strong) NSString* make;
    @property (nonatomic, strong) NSString* model;

@end

为了显示搜索结果,我将 REST API 搜索结果 JSON 映射到 TransientCar 对象,但没有将它们保存到上下文中。默认情况下,如果你映射一个托管对象,RestKit 将调用它的 +object 便利工厂来创建对象并将其插入到当前上下文中(硬编码到 sharedManager 的对象存储的上下文中,顺便说一句!)

这似乎是不可持续的。所以现在我只是使用 NSMutableDictionary 来保存搜索结果数据,直到用户点击详细视图并做一些值得保存真正托管对象的事情:

RKObjectMapping* tempCarMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[tempCarMapping mapKeyPathsToAttributes:
 @"year", @"year",
 @"make", @"make",
 @"model", @"model",
 nil];

这是一个好习惯吗?使用 NSMutableDictionary 作为临时表示,直到用户做了一些保证将新对象插入上下文的事情?我有点喜欢使用原始托管对象子类来表示数据,但不知何故能够将其标记为“不保留”之类的东西,但每次我这样做时,我都觉得我在与框架作斗争(和比赛条件)。我还尝试通过创建一个新的 RKObjectManager 并随后清除其整个上下文来使用临时/一次性上下文,但是 RestKit 的 ActiveRecord 类别的 +managedObjectContext 方法被硬编码为返回:

[[[RKObjectManager sharedManager] objectStore] managedObjectContext];

这会破坏对临时/垃圾数据使用临时上下文的可能性。

【问题讨论】:

    标签: ios cocoa-touch core-data restkit


    【解决方案1】:

    不幸的是,我还没有足够的 StackOverflow 声誉来将此答案放在它所属的位置(作为其他回复的 cmets),但我想补充几点。

    我认为 Evan Cordell 的回答是有缺陷的。当前的 restkit 版本 (0.10.x) 不允许您创建上下文供 RKManagedObjectLoaders 使用,并且 RKObjectManagers 可以存储,但它必须是 RKManagedObjectStore 类型,它明确绑定到 sqllite。 restkit (0.20) 的开发版显然放宽了这一点,因此您可以让它将数据保存到内存数据库中。我确实尝试覆盖 RKManagedObjectStore 方法以使用我提供的上下文,但它没有工作......无论如何,修复似乎并不简单。

    给出的另一个链接Better Approach for Creating Temp Object for Core Data with Restkit 似乎与发布一个对象并在响应中接收相同的对象有关。这是一个与这个问题中提出的不同的问题。

    在 v.0.20.x 发布之前,希望很快就会发布,看来并行类层次结构是唯一的选择。如果我说的不对,欢迎指正!

    【讨论】:

    • RestKit 经常更改,确定它支持什么的最好方法是查看文档。但是,在 1.0 之后它应该不会有太大变化。现在有一种方法可以使用任何持久存储协调器创建 RKManagedObjectStore 并随意添加/删除上下文。
    【解决方案2】:

    首先,我过去曾使用您的方法完成此操作,即拥有两个模型副本,一个用于核心数据,一个用于瞬态(只是一个 NSObject)。这对我来说没有任何问题。

    至于你的其他尝试,我不认为图书馆像你想象的那样强迫你。查看RKManagedObjectStoreNSManagedObject+ActiveRecord 的API。特别是,RKManagedObjectStore 有一个managedObjectContext 属性、一个方法- (NSManagedObjectContext*)newManagedObjectContext 和几个用于合并更改的方法。

    你说得对,[NSManagedObject managedObjectContext] 总是返回 sharedManager 的上下文 - 但这是有道理的,它是一个类方法。否则该类如何知道要返回哪个上下文?但这没有实际意义,因为有很多其他方法可以创建新的上下文并访问它们。或者完全避开它,您可以保留对临时上下文的引用并直接使用它。

    这为您提供了一些选择:拥有多个 ObjectManager,拥有一个对象管理器但从中创建一个临时上下文并仅保留您想要的对象,基于托管对象创建一个临时对象。

    NSMutableDictionary 选项似乎不如其他方法灵活,但我不会说这是“不好的做法”。

    【讨论】:

    • 拥有一个仅从 NSObject 继承的瞬态模型类很好,但我最关心的是保持瞬态模型与 NSManagedObject 版本保持同步。它更多的是代码可维护性问题,而不是技术问题。如果编辑器 > 生成 NSManagedObject 子类有一个“带有镜像的 NSObject 子类”复选框,那就太好了。
    • 当然 - 如果您的模型会随频率发生变化,那么我概述的其他方法之一将是一个不错的选择。
    【解决方案3】:

    你也可以看到这个答案:Better Approach for Creating Temp Object for Core Data with Restkit

    它将避免Evan Cordell的回答中提到的瞬态对象问题,他是RestKit的主要贡献者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      相关资源
      最近更新 更多