简体   繁体   English

使用Core Data的RestKit中临时对象的最佳实践

[英]Best practice for temporary objects in RestKit with Core Data

Background: I have a managed object, Car. 背景:我有一个托管对象,Car。 I have a RESTful search API sitting on localhost/cars/search. 我在localhost / cars / search上有一个RESTful搜索API。 The returned results are Car objects from the server side, but I only want to save the one the user chooses. 返回的结果是来自服务器端的Car对象,但我只想保存用户选择的那个。 The rest of the Cars I want to discard when they tap back out of Search. 当他们退出搜索时,我想要丢弃剩下的汽车。

At first I was all like: 起初我都喜欢:

@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

I was mapping the REST API search results JSON into TransientCar objects for the purposes of displaying search results, but not saving them to the context. 我将REST API搜索结果JSON映射到TransientCar对象以显示搜索结果,但不将它们保存到上下文中。 By default, if you map a managed object, RestKit will call its +object convenience factory to create the object and insert it into the current context (hard-coded to sharedManager's object store's context, btw!) 默认情况下,如果映射托管对象,RestKit将调用其+对象便利工厂来创建对象并将其插入当前上下文(硬编码为sharedManager的对象库的上下文,顺便说一句!)

This seemed unsustainable. 这似乎不可持续。 So now I'm just using NSMutableDictionary to hold the search result data until the user taps into a detail view and does something worth saving a real managed object for: 所以现在我只是使用NSMutableDictionary来保存搜索结果数据,直到用户点击详细视图并执行一些值得保存真实托管对象的内容:

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

Is this a good practice? 这是一个好习惯吗? Using NSMutableDictionary as a temporary representation until the user does something that warrants inserting a new object into the context? 使用NSMutableDictionary作为临时表示,直到用户做了保证在上下文中插入新对象的操作? I was kind of a fan of using the original managed object subclass to represent the data, but somehow being able to flag it as "don't keep" or something, but every time I do that I feel like I'm fighting the framework (and race conditions). 我有点喜欢使用原始托管对象子类来表示数据,但不知何故能够将其标记为“不要保留”或者其他东西,但每次我这样做时我觉得我正在与框架作斗争(和比赛条件)。 I also tried using a scratch/throwaway context by creating a new RKObjectManager and just clearing its whole context afterwards, but RestKit's ActiveRecord category's +managedObjectContext method is hardcoded to return: 我还尝试通过创建一个新的RKObjectManager来使用临时/一次性上下文,然后只是清除其整个上下文,但RestKit的ActiveRecord类的+ managedObjectContext方法被硬编码返回:

[[[RKObjectManager sharedManager] objectStore] managedObjectContext];

That sort of scuttles the possibility of ever using a scratch context for temp/trash data. 这种方式破坏了对临时/垃圾数据使用临时上下文的可能性。

Unfortunately, I don't as yet have enough StackOverflow reputation to put this answer where it belongs (as comments to the other replies), but I wanted to add some points. 不幸的是,我还没有足够的StackOverflow声誉将这个答案放在它所属的地方(作为对其他回复的评论),但我想补充一些观点。

I believe that Evan Cordell's answer is flawed. 我相信Evan Cordell的答案是有缺陷的。 The current restkit version (0.10.x) doesn't let you create contexts for the RKManagedObjectLoaders to use, and the RKObjectManagers can take a store, but it has to be of type RKManagedObjectStore, which is explicitly tied to sqllite. 当前的restkit版本(0.10.x)不允许您为RKManagedObjectLoaders创建上下文,RKObjectManagers可以使用存储,但它必须是RKManagedObjectStore类型,它与sqllite明确绑定。 The dev version of restkit (0.20) apparently relaxes that, so you can have it save the data to an in-memory database. restkit的开发版本(0.20)显然放宽了这一点,因此您可以将数据保存到内存数据库中。 I did try overriding the RKManagedObjectStore methods to use a context I provided, but it didn't work ... at any rate, the fix appears to be non-trivial. 我确实尝试重写RKManagedObjectStore方法以使用我提供的上下文,但它不起作用......无论如何,修复似乎是非平凡的。

The other link given, Better Approach for Creating Temp Object for Core Data with Restkit , appears to do with posting an object and receiving the same object in the response. 给出的另一个链接,即使用Restkit为核心数据创建临时对象的更好方法 ,似乎与发布对象和在响应中接收相同的对象有关。 It's a different problem than was posed in this question. 这是一个与这个问题不同的问题。

Until v.0.20.x is released, which will hopefully be soon, it appears that a parallel class hierarchy is the only choice. 在v.0.20.x发布之前,希望很快就会发布,似乎并行类层次结构是唯一的选择。 If I'm incorrect, I welcome correction on this point! 如果我不对,我欢迎纠正这一点!

First, I've done this in the past using your method of having two copies of the model, one which is for Core Data and one which is transient (just an NSObject). 首先,我在过去使用你的模型的两个副本的方法完成了这个,一个用于Core Data,一个用于瞬态(只是一个NSObject)。 That worked without any problems for me. 这对我没有任何问题。

As for your other attempts, I don't think the library forces your hand as much as you think. 至于你的其他尝试,我不认为图书馆会像你想象的那样强迫你的手。 Look at the API for RKManagedObjectStore and NSManagedObject+ActiveRecord . 查看RKManagedObjectStoreNSManagedObject+ActiveRecord的API。 In particular, RKManagedObjectStore has a managedObjectContext property, a method - (NSManagedObjectContext*)newManagedObjectContext and several methods for merging changes. 特别是,RKManagedObjectStore有一个managedObjectContext属性,一个方法- (NSManagedObjectContext*)newManagedObjectContext和几个合并更改的方法。

You're right that [NSManagedObject managedObjectContext] always returns the sharedManager's context - but that makes sense, it's a class method. 你是对的[NSManagedObject managedObjectContext]总是返回sharedManager的上下文 - 但这是有道理的,它是一个类方法。 Otherwise how would the class know which context to return? 否则,该类将如何知道返回哪个上下文? But it's moot since there are so many other ways to create new contexts and access them. 但这是没有实际意义的,因为有很多其他方法可以创建新的上下文并访问它们。 Or sidestepping that entirely, you could just keep a reference to your temporary context and use it directly. 或者完全回避这一点,您可以保留对临时上下文的引用并直接使用它。

This gives you a few options: have multiple ObjectManagers, have one object manager but create a temporary context from it and only keep the objects you want, create a transient object based on the managed object. 这为您提供了几个选项:拥有多个ObjectManagers,拥有一个对象管理器但从中创建一个临时上下文,只保留您想要的对象,根据托管对象创建一个临时对象。

The NSMutableDictionary option doesn't seem as flexible as the other methods, but I wouldn't say it's "bad practice." NSMutableDictionary选项似乎不像其他方法那样灵活,但我不会说这是“不好的做法”。

You can also see this answer: Better Approach for Creating Temp Object for Core Data with Restkit 您还可以看到这个答案: 使用Restkit为核心数据创建临时对象的更好方法

It will avoid the transient object problem mentioned in the answer by Evan Cordell, who is a major contributor to RestKit. 它将避免Evan Cordell在回答中提到的瞬态对象问题,他是RestKit的主要贡献者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM