Подтвердить что ты не робот

Сохранить объекты CoreData в NSUserDefaults

Представьте себе объект CoreData (например, с именем searchEngine).
NSManagedObjectContext управляет некоторыми "экземплярами" этого объекта.
Конечный пользователь сможет выбрать свой "standard searchEngine" с помощью NSPopupButton.
selected object NSPopupButton должен быть привязан к NSUserDefaults.
Проблема:

1) @try {save}

a) Если вы попытаетесь сохранить выбранный "экземпляр" непосредственно в NSUserDefaults, произойдет следующее:

 - [NSUserDefaults setObject: forKey:]: попытка вставить значение не-свойства '(entity: searchEngine; id: 0x156f60; данные: {   url = " http://google.de/";   someAttribute = 1;   name = "google";
}) 'класса' searchEngine '.
     

b) Если вы попытаетесь преобразовать "экземпляр" в NSData, это будет выглядеть следующим образом:

-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0
     

Итак, любая идея, как получить эти объекты в данных, совместимых с plist?

2) @try {registerDefaults}

Обычно метод registerDefaults: реализуется в + (void)initialize. Проблема здесь в том, что этот метод вызывается до того, как CoreData загрузит сохраненные объекты из своей базы данных. Таким образом, я не могу установить значение по умолчанию для не существующего объекта, не так ли?

Я знаю, длинные вопросы... но: try {[me обеспечить: подробности]}; D

4b9b3361

Ответ 1

Вам не захочется пытаться архивировать основной объект данных и хранить его. Вместо этого вы должны сохранить ключ или какой-либо другой известный атрибут и использовать его для извлечения объекта при запуске приложения.

Пример кода примера (слегка измененный из примера, опубликованного в Руководство по программированию основных данных):

NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
    entityForName:@"SearchEngine" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

NSPredicate *predicate = [NSPredicate predicateWithFormat:
    @"engineName LIKE[c] '%@'", selectedEngineName];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
    // Deal with error...
}

Таким образом вы сохраняете имя в пользовательских значениях по умолчанию и при необходимости извлекаете объект.

Ответ 2

Если вам нужно сохранить ссылку на определенный управляемый объект, используйте представление URI идентификатора управляемого объекта:

NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];

Затем вы можете сохранить URL-адрес пользователя по умолчанию.

Чтобы получить управляемый объект, вы используете:

NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL];
NSManagedObject *myManagedObject = [myContext objectWithID:moID];

Единственное предостережение заключается в том, что вы должны убедиться, что исходный идентификатор управляемого объекта является постоянным - это не проблема, если вы уже сохранили объект, иначе вы можете использовать obtainPermanentIDsForObjects:error:.

Ответ 3

Здесь самый чистый и самый короткий способ сделать это с помощью методов setURL и getURL, добавленных в 4.0, чтобы избежать дополнительных вызовов NSKeyedUnarchiver и NSKeyedArchiver:

сеттер:

 + (void)storeSomeObjectId:(NSManagedObjectID *)objectId
 {
     [[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation] 
                                            forKey:@"someObjectIdKey"];
     [[NSUserDefaults standardUserDefaults] synchronize];
 }

Getter:

 + (SomeManagedObject *)getObjectByStoredId
 {
     NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:@"someObjectIdKey"];
     NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri];
     SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId];
 }