Як отримати об’єкт Core Data з конкретного ідентифікатора об'єкта?


120

Я легко можу отримати ідентифікатор об’єкта в Core Data, використовуючи наступний код:

NSManagedObjectID *moID = [managedObject objectID];

Однак чи існує спосіб вивести об'єкт із основного сховища даних, надавши йому специфічний ідентифікатор об'єкта? Я знаю, що я можу це зробити за допомогою NSFetchRequest, як це:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(objectID = %@)", myObjectID];
[fetchRequest setPredicate:predicate];

Однак я хотів би зробити це таким чином, що не ініціює власний запит на отримання. Будь-які ідеї?


Але за допомогою способу отримання запиту ви можете встановити властивості або відносини заздалегідь встановленими, що дасть вам кращу ефективність, а не багато інших запитів під час доступу до речей.
мальха

Відповіді:


208

Ти хочеш:

-(NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID
                                   error:(NSError **)error

Вилучає об’єкт із магазину, який має цей ідентифікатор, або нульовий, якщо його не існує.

(Будьте в курсі: на NSManagedObjectContext є два способи з подібними схожими іменами, які мене змусили. Щоб допомогти їм у прямому розумінні, ось що робити двоє інших:

-(NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID

... створить об'єкт несправності за допомогою наданого objectID, незалежно від того, існує такий об’єкт у магазині чи ні. Якщо його не існує, все, що викликає помилку, вийде з ладу, якщо ви спочатку не вставите об'єкт разом з NSManagedObjectContext insertObject:. Єдине використання, яке я знайшов для цього, - це копіювання об'єктів з магазину в магазин, зберігаючи ObjectID.

-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID

... поверне об'єкт, який має цей ідентифікатор, якщо він був вилучений з магазину цим керованимObjectContext. Якщо хтось знає, для чого цей метод корисний, будь ласка, прокоментуйте його.)

[ета .: Ще одна важлива відмінність першого методу від двох інших полягає в тому, що existingObjectWithID:error:ніколи не повертає помилку; він завжди отримує весь предмет для вас. Якщо ви намагаєтеся цього уникнути (наприклад, працюючи з дорогим для отримання об'єктом з великим властивістю краплі), ви повинні бути розумними з, objectWithID:або objectRegisteredForID:які не видають помилок; або використовувати правильно налаштований запит на отримання.]


11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDймовірно, корисно, коли ви просто хочете дізнатись, чи існує об'єкт у контексті, і не хочете його витягувати.
Тоні

Моє положення. У -tableView:didSelectRowAtIndexPath: UIAlertView з так / ні відображається. На "так" - є якась робота з об'єктом. Я використовую NSFetchedResultsController+ фонові оновлення CoreData з віддаленого. Тому я не можу зберігати об’єкт: поки на екрані оповіщення, сховище можна оновити та об’єкт видалити. Я зберігаю objectId, після чого ще раз витягую його в делегат попередження. Тому що я використовую NSFetchedResultsController- до цього моменту всі необхідні об’єкти вже в контексті. Більше того, коли немає жодного об'єкта в контексті, CoreData не повинен робити марних спроб вибору.
kpower

приємна відповідь, дякую! ці назви методів справді хитрі. легко зіпсувати все з неправильним
шакал

Чудова відповідь, спасибі за роз’яснення щодо objectWithId:- необхідність insertObjectспочатку закликати запобігти підвищенню винятку при спробі вчинити помилку була для мене справді не очевидною.
Станіслав Панькевич

3
objectRegisteredForID:корисно, коли у вас є список об’єктівID від операції в іншому контексті, і ви хочете оновлювати лише ті, які можуть мати несвіжі дані в локальному контексті. Це тримає ваш графік об'єкта (і, отже, використання пам'яті) під контролем, і краще, ніж -registeredObjectsпрокручувати та перевіряти objectID, щоб побачити, чи не виправданий об'єкт у вашому контексті.
Стерлінг Арчер

4

objectWithID:це метод, який ви шукаєте, і це рекомендований спосіб зробити це. objectWithID:буде ефективно використовувати NSManagedObjectContext, щоб витягнути об'єкт лише стільки рівнів, скільки потрібно - на відміну від деяких інших засобів для цього. objectWithID:буде правильно використовувати інформацію в пам'яті у батьківських контекстах, постійному координаторі магазину та самому постійному сховищі перед переходом до резервного сховища.

Це глибоко висвітлено в сесії WWDC 2012 «Основні дані найкращих практик».


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.