Използване на подкласове NSManagedObject за транспортиране на постоянни и непостоянни данни

Имам някои мисли как да използвам подкласовете NSManagedObject на някои основни данни за обработка на постоянни данни и непостоянни данни.

Да приемем, че имате приложение за рецепти, показващо списък с вашите собствени рецепти от CoreData и в същото това приложение можете да търсите рецепти и за други потребители. Тези други потребителски рецепти, разбира се, са от API и ние не искаме да ги запазваме в основните данни. Но това, което искаме вместо това, е нашият контролер за изглед на подробности за рецептата да действа по един и същи начин, независимо дали му е дадена постоянна или непостоянна рецепта. Естествено смятам, че тогава трябва да използваме същата обвивка на обекта около нашите данни и да оставим нашия View Controller да бъде сляп за произхода на данните.

Проблемът е, че подкласовете на NSManagedObject не могат да бъдат инициализирани ръчно и трябва да бъдат вмъкнати в контекста. Това не е добре за рецептите на другите ни потребители. От друга страна за нашите собствени рецепти имаме нужда тези обекти да бъдат вмъкнати в контекста.

Имам предвид няколко решения, но наистина бих искал да прочета какво мислите вие ​​по този проблем.

Бихте ли казали, че това е някакъв проблем с внедряването и трябва да бъде разрешен чрез обвиване на двата обекта с данни в един обект? Например чрез замяна на всички гетери и сетери за обработка както на обекти на Coredata, така и на обекти на NSDictionary?

Или това е проблем с архитектурата и бихте го разрешили, например като вложите NSManagedContext или използвате множество постоянни хранилища (едно в паметта, а другото Sqlite)?


person Iman Zarrabian    schedule 11.04.2013    source източник


Отговори (3)


Всъщност можете да създадете екземпляри на NSManagedObject, без да ги вмъквате в контекст. Просто предайте nil като аргумент на контекста на управлявания обект. Направете нещо като:

NSEntityDescription *myRecipeEntity = [NSEntityDescription entityForName:@"MyRecipeEntity" inManagedObjectContext:[self managedObjectContext]];
MyRecipeClass *recipe = [[MyRecipeClass alloc] initWithEntity:myRecipeEntity insertIntoManagedObjectContext:nil]];

Сега имате екземпляр на рецепта, който не е в никакъв контекст.

Ако по-късно искате да го добавите към контекст:

[[self managedObjectContext] insertObject:recipe];

Ако не искате да го поставите, просто го изхвърлете.

person Tom Harrington    schedule 11.04.2013
comment
Не можете да имате връзки между обекти, които не са вмъкнати в контекста, доколкото знам. - person svena; 11.04.2013
comment
Сигурен. Но това не винаги има значение. - person Tom Harrington; 12.04.2013
comment
Thx, това може да е решение... Ще го пробвам и ще ви уведомя - person Iman Zarrabian; 12.04.2013
comment
Хей, това наистина изглежда работи и си прав в моя случай липсата на връзки за временни обекти всъщност не е важното. Между другото initWithEntity:insertIntoManagedObjectContext: изглежда е метод на екземпляр, а не метод на клас и може да се използва като всеки друг init метод. Thx много, приемам този отговор точно сега ;) - person Iman Zarrabian; 12.04.2013
comment
Написах демонстрация за това в OSX и имах проблеми, при които атрибутите не се записваха (вижте github.com/seltzered/ CoreDataMagicalRecordTempObjectsDemo). От моите резултати изглежда, че използването на детски контекст е по-безопасен подход, както се предлага в подобен въпрос - stackoverflow.com/a/14494126/ 314780 - person Vivek Gani; 24.06.2014
comment
Неуспешната версия съдържа ли се някъде в този проект? Няма причина използването на основни данни с описания по-горе подход да не запази атрибути. Без да видите кода е невъзможно да кажете защо не работи за вас, но е възможно това да е страничен ефект от добавянето на Magical Record. - person Tom Harrington; 24.06.2014
comment
Да, моят подход да използвам обект с нулев контекст и след това да го вмъкна в контекст по подразбиране е маркираната секция: github.com/seltzered/CoreDataMagicalRecordTempObjectsDemo/blob/, извинения, че набързо хвърлих всичко това в приложениетоDidFinishLaunching. - person Vivek Gani; 25.06.2014

Вероятно просто ще използвам отделен контекст, който никога не запазвате, това изглежда е най-простият маршрут.

person Chris Wagner    schedule 11.04.2013

Конфигурации на модела - съхраняване в паметта и поддържано от sqlite хранилище.

Сериозно бих обмислил използването на конфигурации на модели и два типа постоянни магазини: in-memory и sqlite backed.

Но това също означава, че ще трябва да създадете отделни обекти за данни за изтегляне, което донякъде анулира идеята, че можете да имате някои от рецептите постоянни, а някои временни, докато и двете са рецепти. Освен това не можете да имате връзки между обекти в различни постоянни хранилища. Ще се откажете от ползата от обратните връзки и ще трябва да имитирате това с извлечени свойства например.

Като цяло, това е жизнеспособен избор с някои недостатъци.

Контекст на изолиран управляван обект

Най-голямото предимство на използването на отделни контексти на управлявани обекти е, че можете да използвате един и същ обект на рецепта както за постоянни, така и за временни данни. Ще трябва да избягвате запазването на временния контекст и ще трябва да внесете всички промени от постоянното хранилище или да се слеете от друг контекст, който съдържа данните, които запазвате.

Предизвикателството с тази алтернатива е, че трябва да изградите по-голямата част от потребителския си интерфейс върху този изолиран контекст за четене, но всички постоянни промени, които правите, трябва да бъдат запазени в основния ви контекст и разпространени обратно чрез сливане в изолирания контекст. Това може да доведе до някои трудни ситуации, но според мен е възможно.

person svena    schedule 11.04.2013