如何使用核心数据模型而不保存它们?

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

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

这是我的class级:

@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 = [字典等等等应用程序崩溃这个错误

由于未捕获的exception'NSInvalidArgumentException',原因:' – [海报setPosterID:]:无法识别的select器发送到实例0xaa8b160'

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

我该如何解决这个问题?

你不能仅仅alloc/init一个pipe理对象,因为一个pipe理对象必须与一个pipe理对象上下文关联。 poster.posterID = ...崩溃,因为dynamic创build的存取方法在没有托pipe对象上下文的情况下不起作用。 ( 更正:正如@noa所说的,只要你使用了指定的初始化器,你就可以创build没有托pipe对象上下文的对象,但是这些对象对于任何获取请求都是不可见的。

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

我不能告诉你如何用MagicalRecord来做到这一点,但用“普通的核心数据”就可以这样工作:

创build托pipe对象上下文和持久性核心协调器后,将两个持久性存储分配给商店协调人:

 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 ,这将是适当的方法为此configuration。

您也可以尝试使用指定的初始化程序-initWithEntity:insertIntoManagedObjectContext: nil作为第二个参数。 (根据我的经验,pipe理对象的某些方面在没有上下文的情况下工作正常,而另一些方面则没有。

这个答案有一些进一步的解释。