Вопрос

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

1) @попробовать{сохранить}

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

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60  ; data: {
    url = "http://google.de/";
    someAttribute = 1;
    name = "google";
})' of class 'searchEngine'.

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

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

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

2) @try{Ошибки при регистрации}

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

Я знаю, длинные вопросы...но:попробуйте{[я предоставлю: подробности]};D

Это было полезно?

Решение

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

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

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...
}

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

Другие советы

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

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

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

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

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

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

Вот самый чистый и короткий способ на данный момент сделать это с использованием методов 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];
 }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top