Как мне создать описание NSFetchedPropertyDescription программно?

#objective-c #xcode #core-data #fetched-property

#objective-c #xcode #core-data #извлеченное свойство

Вопрос:

У меня есть уже существующее описание, NSManagedObjectModel которое я создал с помощью графического интерфейса Xcode. Я хочу создать отсортированное полученное свойство, графический интерфейс Xcode 3.2 которого не поддерживает. Я делаю все это перед созданием своего, NSPersistentStoreCoordinator потому что я знаю, что вы не можете изменить NSManagedObjectModel после того, как диспетчер графов объектов начал его использовать. Я создал NSFetchedPropertyDescription таким образом:

 NSManagedObjectModel *managedObjectModel = ... // fetch from my mainBundle

NSEntityDescription *fetchedPropertyEntityDescription = [entitiesByName objectForKey:@"MyEntity"];

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:fetchedPropertyEntityDescription];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"myPredicateProperty == $FETCH_SOURCE"]];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"mySortProperty" ascending:YES]]];

NSFetchedPropertyDescription *fetchedPropertyDescription = [[[NSFetchedPropertyDescription alloc] init] autorelease];
[fetchedPropertyDescription setFetchRequest:fetchRequest];
[fetchedPropertyDescription setName:@"myFetchedProperty"];

NSEntityDescription *entityDescription = [entitiesByName objectForKey:@"MyFetchSourceEntity"];

[entityDescription setProperties:[[entityDescription properties] arrayByAddingObject:fetchedPropertyDescription]];
  

Когда я вызываю

 [fetchedPropertyDescription setFetchRequest:fetchRequest];
  

Я получаю следующее исключение:

 NSInvalidArgumentException: Can't use fetch request with fetched property description (entity model mismatch).
  

Ответ №1:

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

Это относится и к полученным свойствам. Из документов NSFetchProperyDescription:

Выбранные описания свойств доступны для редактирования до тех пор, пока они не будут использованы менеджером графов объектов. Это позволяет создавать или изменять их динамически. Однако, как только описание используется (когда управляемая объектная модель, к которой оно принадлежит, связана с координатором постоянного хранилища), оно не должно (действительно, не может) быть изменено. Это выполняется принудительно во время выполнения: любая попытка изменить модель или любой из ее объектов после того, как модель связана с координатором постоянного хранилища, вызывает выдачу исключения. Если вам нужно изменить используемую модель, создайте копию, измените копию, а затем удалите объекты со старой моделью.

Комментарии:

1. Да, но я еще не создал NSPersistentStoreCoordinator с помощью NSManagedObjectModel. Я обновлю свой вопрос.

Ответ №2:

Мне нужно было добавить NSFetchedPropertyDescription в NSEntityDescription перед установкой NSFetchRequest на NSFetchedPropertyDescription .

Необходимые шаги приведены ниже:

 NSManagedObjectModel *managedObjectModel = ... // fetch from my mainBundle

NSEntityDescription *fetchedPropertyEntityDescription = [entitiesByName objectForKey:@"MyEntity"];

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:fetchedPropertyEntityDescription];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"myPredicateProperty == $FETCH_SOURCE"]];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"mySortProperty" ascending:YES]]];

NSFetchedPropertyDescription *fetchedPropertyDescription = [[[NSFetchedPropertyDescription alloc] init] autorelease];
//DON'T DO THIS HERE, AN ERROR WILL OCCUR
//[fetchedPropertyDescription setFetchRequest:fetchRequest];
//
[fetchedPropertyDescription setName:@"myFetchedProperty"];

NSEntityDescription *entityDescription = [entitiesByName objectForKey:@"MyFetchSourceEntity"];

[entityDescription setProperties:[[entityDescription properties] arrayByAddingObject:fetchedPropertyDescription]];

//DO THIS HERE INSTEAD
[fetchedPropertyDescription setFetchRequest:fetchRequest];