如何使用Core Data模型而不保存它们?

时间:2012-12-22 15:34:09

标签: objective-c ios core-data magicalrecord

我正在编写一个应用程序,我正在使用MagicalRecord作为与Core Data交互的框架。应用程序从服务器获取一系列海报,然后显示它们。也可以在应用程序上创建海报,然后在用户需要时将其上传到服务器。

因此,用户创建的海报使用Core Data存储在本地数据库中,而从服务器获取的海报应仅显示在应用程序中,但不能保存在本地。我如何使用相同的Poster类(现在是NSManagedObject的子类)来处理这两种情况?

这是我的班级:

@interface Poster : NSObject
@property (nonatomic, retain) NSNumber * posterID;
@property (nonatomic, retain) NSString * artists;
@end

当我从服务器获取海报数组时,我会分配一个新的海报,然后分配属性:

Poster *poster = [[Poster alloc] init];
if ([dict objectForKey:@"id"]) poster.posterID = [dict objectForKey:@"id"];
if ([dict objectForKey:@"artists"]) poster.artists = [dict objectForKey:@"artists"];

但是当到达链接的poster.posterID = [dict等等时,应用程序崩溃时出现此错误

  

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:' - [海报setPosterID:]:无法识别的选择器发送到实例0xaa8b160'

如果我用Poster *poster = [Poster createEntity];而不是Poster *poster = [[Poster alloc] init];创建新对象,应用程序不会崩溃,但是当我保存上下文时,我发现从服务器获取的所有海报都保存在本地。 / p>

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:12)

您不能只是alloc/init托管对象,因为托管对象必须与托管对象上下文相关联。 poster.posterID = ...崩溃,因为没有托管对象上下文,动态创建的访问器方法不起作用。 (更正:正如@noa所说,只要您使用指定的初始值设定项,就可以创建没有托管对象上下文的对象。但这些对象对任何提取请求都不会“可见”。)

要创建不应保存到磁盘的托管对象,您可以使用两个持久性存储:一个SQLite存储和一个单独的内存存储。

我不能告诉你如何用MagicalRecord做到这一点,但是使用“普通核心数据”它会像这样工作:

在创建托管对象上下文和持久核心协调器之后,将两个持久性存储分配给商店协调员:

NSPersistentStore *sqliteStore, *memStore;

sqliteStore = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error];
if (sqliteStore == nil) {
    // ...
}
memStore = [coordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error];
if (memStore == nil) {
    // ...
}

稍后,当您将新对象插入上下文时,您将新对象与SQLite存储或内存存储关联:

Poster *poster = [NSEntityDescription insertNewObjectForEntityForName:@"Poster" inManagedObjectContext:context];
[context assignObject:poster toPersistentStore:memStore];
// or: [context assignObject:poster toPersistentStore:sqliteStore];
poster.posterID = ...;
poster.artists = ...;

只有分配给SQLite存储的对象才会保存到磁盘。如果重新启动应用程序,分配给内存存储的对象将会消失。我认为未明确分配给商店的对象会自动分配给第一个商店,在这种情况下将是SQLite商店。

我还没有使用过MagicalRecord,但我发现有方法MR_addInMemoryStoreMR_addSqliteStoreNamed,这将是此配置的合适方法。

答案 1 :(得分:2)

您还可以尝试将指定的初始化程序-initWithEntity:insertIntoManagedObjectContext:与nil一起用于第二个参数。 (根据我的经验,托管对象的某些方面在没有上下文的情况下工作正常;其他方面则没有。)

this answer中有一些进一步的解释。