SetPropertiesToFetch, похоже, не имеет никакого эффекта

Я пытаюсь использовать setPropertiesToFetch в моем запросе выборки, чтобы ограничить данные, которые извлекаются из моего магазина, но, похоже, это не влияет. Когда я использую его и отображаю объект, возвращенный в консоль, я вижу, что все мои свойства есть. Те же данные отображаются, устанавливаю ли я свойства или нет. Все отношения отображаются как ошибки, но все данные для атрибутов есть.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:context];
NSDictionary *entityProperties = [entity propertiesByName];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
[fetchRequest setIncludesPendingChanges:NO];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:[entityProperties objectForKey:@"myAttrib"], nil]];

Кажется, что выборка возвращает те же данные для каждого объекта с этой последней строкой или без нее. Любые идеи?

Ответ 1

Впечатление, которое у меня было (из того, что сказали инженеры Apple), было то, что данные будут ошибочно введены для непривилегированных свойств, как только вы использовали аксессоров для этого свойства. Возможно, что при генерации описания объекта NSManagedObject эти аксессоры используются для каждого свойства, в результате чего данные должны быть сведены к ошибкам непосредственно перед тем, как генерируется строка, описывающая объекты.

Вы можете попробовать использовать инструменты Core Data Faults и/или Core Data Cache Misses (в симуляторе), чтобы увидеть, когда действительно происходят сбои. Если они произойдут до того, как вы распечатаете управляемые объекты, это, похоже, поддержит мое предположение выше.

Ответ 2

Раздел "Особые соображения" документации для setPropertiesToFetch: говорит

Это значение используется, только если для параметра resultType установлено значение NSDictionaryResultType.

Ваш фрагмент кода не устанавливает resultType. Возможно, вы хотели использовать setRelationshipKeyPathsForPrefetching:?

Ответ 3

попробуйте setReturnsDistinctРезультаты: YES

из документов apple:

setReturnsDistinctResults:

Устанавливает, должен ли запрос возвращать только отдельные значения для полей, заданных свойствамиToFetch.

  • (недействительными) setReturnsDistinctResults: (BOOL) значения

Параметры значения Если ДА, запрос возвращает только отдельные значения для полей, заданных свойствамиToFetch.

Ответ 4

Правильный способ использования setPropertiesToFetch

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setResultType:NSDictionaryResultType]; // Remember to setResultType
[fetchRequest setPropertiesToFetch:
[NSArray arrayWithObjects:@"name", @"age", nil]]; 
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest
                                                               error:nil];

NSArray *nameArray = [results valueForKey:@"name"];
NSArray *ageArray = [results valueForKey:@"age"];

Результаты не являются массивом объектов Person, а массив Словарь. Вы можете получить доступ к Словари внутри, таким образом

NSLog(@"%@", [results[0] valueForKey:@"name"]);
NSLog(@"%@", [results[0] valueForKey:@"age"]);

Если вы хотите работать только с объектом Model (который CoreData извлекает все свойства/атрибуты объекта), вы можете создать свою модель с Person и PersonDetail (которая содержит подробную информацию о человеке). Таким образом

  • Вы можете выполнить fetchRequest и получить массив объектов Person
  • При доступе к aPerson.detail(детальность является отношением "один к одному" с PersonDetail), CoreData будет выполнять ошибки для вас