Я могу легко получить идентификатор объекта в 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];
Однако я бы хотел сделать это таким образом, чтобы не инициировать собственный запрос на выборку. Любые идеи?
Ответы:
Вы хотите:
Выбирает объект из магазина с этим идентификатором или nil, если он не существует.
(Имейте в виду: есть два метода в NSManagedObjectContext с похожими именами, которые меня сбили с толку. Чтобы помочь им понять, вот что делают два других:
... создаст объект ошибки с предоставленным идентификатором объекта, независимо от того , существует ли такой объект в хранилище или нет. Если его не существует, все, что вызывает ошибку, завершится ошибкой, если вы сначала не вставите объект с помощью NSManagedObjectContext
insertObject:
. Единственное использование, которое я нашел для этого, - это копирование объектов из магазина в хранилище с сохранением ObjectID.... вернет объект с этим идентификатором, если он был получен из хранилища этим managedObjectContext. Если кто знает, чем полезен этот метод, прокомментируйте.)
[eta .: Еще одно важное отличие первого метода от двух других заключается в том, что он
existingObjectWithID:error:
никогда не возвращает ошибку; он всегда получает за вас весь объект. Если вы пытаетесь этого избежать (например, работая с дорогостоящим для извлечения объектом с большим свойством blob), вы должны быть умны сobjectWithID:
илиobjectRegisteredForID:
, которые не вызывают ошибок; или используйте правильно настроенный запрос на выборку.]источник
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID
вероятно, полезно, когда вы просто хотите увидеть, существует ли уже объект в контексте, и не хотите его получать.-tableView:didSelectRowAtIndexPath:
UIAlertView отображается да / нет. На «да» - есть работа с объектом. Я используюNSFetchedResultsController
+ фоновые обновления CoreData удаленно. Поэтому я не могу сохранить объект: пока на экране отображается предупреждение, хранилище можно обновить, а объект удалить. Я сохраняю objectId, а затем снова получаю его в делегате предупреждения. Потому что используюNSFetchedResultsController
- все необходимые объекты к этому моменту уже находятся в контексте. Более того, когда в контексте нет объекта, CoreData не должен делать бесполезные попытки выборки.objectWithId:
- необходимостьinsertObject
сначала позвонить, чтобы предотвратить возникновение исключения при попытке запустить ошибку, действительно была для меня неочевидной.objectRegisteredForID:
полезно, когда у вас есть список идентификаторов объектов из операции в другом контексте, и вы хотите обновить только те, которые могут иметь устаревшие данные в локальном контексте. Это контролирует ваш граф объектов (и, следовательно, использование памяти), и это лучше, чем перебирать-registeredObjects
и проверять идентификаторы объектов, чтобы увидеть, не поврежден ли объект для вашего контекста.objectWithID:
- это метод, который вы ищете, и это рекомендуемый способ.objectWithID:
будет эффективно использовать NSManagedObjectContext для извлечения объекта только на столько уровней, сколько необходимо - в отличие от некоторых других средств для этого.objectWithID:
будет правильно использовать информацию в памяти в родительских контекстах, координаторе постоянного хранилища и самом постоянном хранилище перед переходом в резервное хранилище.Это подробно рассматривается в сеансе WWDC 2012 «Лучшие практики работы с основными данными».
источник
Версия Swift 5:
https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506686-existingobject
также есть методы
object(with:)
илиregisteredObject(for:)
. В зависимости от того, что вам нужно.источник