NSManagedObjectID в NSData
Вопрос
Я нашел этот замечательный NSManagedObjectID.Это было бы очень удобно для ссылки на Entity/NSManagedObject/NSEntityDescription, верно?
Давайте получим идентификатор от сущности:
NSEntityDescription *entity = [self newEntity];
NSManagedObjectID *objID = [entity objectID];
Так...есть идеи, как это получить objID
в строку?Или лучше:НСдата.На самом деле что-то, чтобы иметь возможность сохранить его в NSUserDefaults.;-)
Кстати:NSFetchRequest не хочет работать в моем случае.Я использую модифицированную версию этого примера: ответ на старый вопрос.
Решение
Чтобы получить архивированный URI, соответствующий NSManagedObject
's objectID
:
NSManagedObject* myMO;
...
NSURL *uri = [[myMO objectID] URIRepresentation];
NSData *uriData = [NSKeyedArchiver archivedDataWithRootObject:uri];
Чтобы вернуться к экземпляру исходного управляемого объекта, вам понадобится стек CoreData с постоянным хранилищем, содержащим этот экземпляр. уже добавлено к NSPersistentStoreCoordinator
.Затем:
NSData *uriData;
NSPersistentStoreCoordinator *psc;
NSManagedObjectContext *moc; //with moc.persistentStoreCoordinator = psc.
...
NSURL *uri = [NSKeyedUnarchiver unarchiveObjectWithData:uriData];
NSManagedObjectID *moID = [psc managedObjectIDForURIRepresentation:uri];
NSManagedObject *myMO = [moc objectWithID:moID];
Другие советы
Из NSManagedObjectID документация:
Идентификаторы объектов могут быть преобразованы в представление URI, которое можно заархивировать и воссоздать позже, чтобы вернуться к данному объекту (с помощью ManagedObjectIdforurRepresentation:(Nspersistentstorecoordinator) и Object Withithid:(НСманажедобжектконтекст).Например, последняя выбранная группа в приложении может быть сохранена в по умолчании пользователя через идентификатор объекта группы.Вы также можете использовать представления ID объекта для хранения «слабых» отношений в постоянных магазинах (где невозможно жесткого соединения).
Просто превратите его в URL-адрес, а затем в строку или данные.
Вы посмотрели на URIПредставление?NSURL легко преобразовать в NSString, а затем в NSData.
Вам не нужно преобразовывать NSURL в NSString перед архивированием.Просто заархивируйте NSURL.
Редактировать:Недавно я узнал, что идентификатор объекта может измениться, например, после миграции.Поэтому кажется не очень хорошей идеей сохранять идентификатор на диске, ожидая, что позже можно будет ссылаться на объект.
Вот самый чистый и короткий способ, который я нашел на данный момент, с использованием методов setURL и getURL, добавленных в версии 4.0, чтобы избежать дополнительных вызовов NSKeyedUnarchiver и NSKeyedArchiver:
Сеттер:
+ (void)storeSomeObjectId:(NSManagedObjectID *)objectId
{
[[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation]
forKey:@"someObjectIdKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Геттер:
+ (SomeManagedObject *)getObjectByStoredId
{
NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:@"someObjectIdKey"];
NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri];
SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId];
}
Как сказал @preston, вместо этого не сохраняйте идентификатор объекта на диск:
- Создайте новый атрибут для вашей сущности под названием «id».
- Создайте новый атрибут родительской сущности вашей сущности под названием «myEntitysMaxId».
- Переопределите родительскую реализацию ваших объектов «addNewMyEntityObject:»
- Там увеличьте «myEntitysMaxId» и установите это значение в качестве идентификатора нового объекта.
- Делайте то, что обычно делаете, когда извлекаете объект на основе его атрибутов!
Гораздо чище и лучше!