Вопрос по core-data, ios, magicalrecord, objective-c – Как использовать модели Core Data, не сохраняя их?

8

Я пишу приложение и использую 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», причина: «- [Poster setPosterID:]: нераспознанный селектор, отправленный экземпляру 0xaa8b160»

Если я создаю новый объект сPoster *poster = [Poster createEntity]; вместоPoster *poster = [[Poster alloc] init];приложение не падает, но когда я сохраняю контекст, я обнаруживаю, что все постеры, извлеченные с сервера, сохраняются локально.

Как я могу решить это?

Ваш Ответ

1   ответ
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_addInMemoryStore а такжеMR_addSqliteStoreNamed, которые будут подходящими методами для этой конфигурации.

Хороший ответ, хотя по моему опыту динамические средства доступа будут по-прежнему работать без MOC, при условии, что вы используете назначенный инициализатор (с nil для второго параметра). paulmelnikow
@noa: Спасибо за отзыв, и вы правы, что возражаетМожно быть создан без MOC (я исправлю эту часть моего ответа). - Преимущество этой настройки заключается в том, что временные объекты находятся в одном и том же MOC и поэтому могут отображаться с использованием запроса выборки или контроллера полученных результатов. ОП сказал, что «постеры, полученные с сервера, должны отображаться только в приложении», поэтому это решение показалось мне лучше. Martin R

Похожие вопросы