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

Pao*_*rio 8 core-data objective-c ios magicalrecord

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

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

这是我的班级:

@interface Poster : NSObject
@property (nonatomic, retain) NSNumber * posterID;
@property (nonatomic, retain) NSString * artists;
@end
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

我怎么解决这个问题?

Mar*_*n R 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) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

Poster *poster = [NSEntityDescription insertNewObjectForEntityForName:@"Poster" inManagedObjectContext:context];
[context assignObject:poster toPersistentStore:memStore];
// or: [context assignObject:poster toPersistentStore:sqliteStore];
poster.posterID = ...;
poster.artists = ...;
Run Code Online (Sandbox Code Playgroud)

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

我还没有MagicalRecord工作,但我看到有方法MR_addInMemoryStoreMR_addSqliteStoreNamed,这将是该配置适当的方法.