Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
650 views
in Technique[技术] by (71.8m points)

objective c - How to use Core Data models without saving them?

I'm writing an application and I am using MagicalRecord as a framework for interacting with Core Data. The application fetches an array of posters from a server and then displays them. Posters can also be created on the app and then uploaded to the server if the user requires it.

So posters created by the user are stored in the local db using Core Data, while posters fetched from the server should only be displayed in the app but not saved locally. How can I use the same Poster class (which now is a subclass of NSManagedObject) to handle both these cases?

Here is my class:

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

When I fetch the posters array from the server I allocate a new poster and then assign attributes:

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

But when reaching the linked poster.posterID = [dict etc etc the application crashes with this error

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Poster setPosterID:]: unrecognized selector sent to instance 0xaa8b160'

If I create the new object with Poster *poster = [Poster createEntity]; instead of Poster *poster = [[Poster alloc] init];, the app doesn't crash, but when I save the context I find all the posters fetched from the server are saved locally.

How can I solve this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You cannot just alloc/init a managed object, because a managed object must be associated with a managed object context. poster.posterID = ... crashes because the dynamically created accessor methods do not work without a managed object context. (Correction: As @noa correctly said, you can create objects without a managed object context, as long as you use the designated initializers. But those objects would not be "visible" to any fetch request.)

To create managed objects that should not be saved to disk you can work with two persistent stores: one SQLite store and a separate in-memory store.

I cannot tell you how to do that with MagicalRecord, but with "plain Core Data" it would work like this:

After creating the managed object context and the persistent core coordinator, you assign two persistent stores to the store coordinator:

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) {
    // ...
}

Later, when you insert new objects to the context, you associate the new object either with the SQLite store or the in-memory store:

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

Only the objects assigned to the SQLite store are saved to disk. Objects assigned to the in-memory store will be gone if you restart the application. I think that objects that are not assigned explicitly to a store are automatically assigned to the first store, which would be the SQLite store in this case.

I haven't worked with MagicalRecord yet, but I see that there are methods MR_addInMemoryStore and MR_addSqliteStoreNamed, which would be the appropriate methods for this configuration.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...