Извлеченное свойство в основных данных, возвращающее неправильный счет - PullRequest
1 голос
/ 14 декабря 2011

У меня есть отношение к основным данным, которое выглядит следующим образом

ItemA - >> ItemB

где в качестве элемента А есть множество элементов Б. я хотел использовать извлеченное свойство, которое позволило мне получить все связанные с itemB, которые были связаны с itemA, у которых свойство статуса int32 было установлено как «2». Итак, я создал извлеченное свойство в моделировщике данных, которое имело следующее:

извлеченное свойство: completeItem предикат: статус == 2 пункт назначения: itemB

когда я впервые попробовал это, я получил предметы обратно и подумал, что все было круто и сделано, потом я заметил странное поведение, и когда я посмотрел ближе, то предметы, которые он возвратил, не имели ничего общего с фактическим количеством itemB, которое был связан с объектом itemA. Еще более странным является то, что тип возвращаемого значения - NSFaultingMutableArray. Вот быстрый пример

  • У ItemA есть 0 из itemB
  • фильтрованный поиск предиката по свойству NSSet ItemA имеет ItemB возвращает 0
  • извлеченное свойство "completeItem" возвращает 4 элемента ItemB
  • тип, который он возвращает, NSFaultingMutableArray

Это просто странно в моей голове сейчас и действительно не имеет смысла. есть идеи?

ОБНОВЛЕНИЕ 1:

кажется, что указанное здесь извлеченное свойство получает все объекты ItemB, которые должны предлагаться основными данными, которые соответствуют предикату, даже если он не связан с рассматриваемым ItemA

Ответы [ 3 ]

2 голосов
/ 14 декабря 2011

Вот ответ на все эти странности в этом вопросе:

1) Извлеченные свойства действительно не возвращали объекты ItemB только для ItemA.Чтобы это произошло, вы должны добавить что-то подобное в предикат выбранных свойств

status == 2 AND ItemA == $FETCH_SOURCE

2) Из документации по выбранным свойствам:

Полученосвойство оценивается лениво и впоследствии кэшируется.

Если объекты в целевом объекте изменены, необходимо повторно оценить выбранное свойство, чтобы убедиться в его актуальности.Вы используете refreshObject: mergeChanges: для ручного обновления свойств - это вызывает повторное выполнение запроса выборки, связанного с этим свойством, при следующем вызове объекта.

, поэтому в основном используйте refreshObject: mergeChanges , чтобы вручную обновить объект для перезагрузки извлеченного свойства.Вы можете сделать это, добавив метод refresh или выполнив некоторую причудливую переопределение для метода get KVC внутри своего подкласса NSManagedObject.

Как уже говорилось, у других здесь (Роб Бут, Grady Player) есть и другие действительные решения:полностью обходя извлеченные свойства.Пока это Faril

0 голосов
/ 14 декабря 2011

Кайл, проблема в том, что Core Data пытается быть умнее тебя. Core Data не хочет заполнять вашу память всеми объектами в вашем хранилище данных, если вы не собираетесь их использовать. Таким образом, вместо того, чтобы создавать реальные объекты все время, он создает «Неисправности». Ошибки являются заполнителями для реальных объектов, и когда вы запрашиваете эти объекты, Core Data отправляется и заполняет объекты в это время.

Мое лучшее предположение состоит в том, что ваш поиск по свойству ItemA.ItemB не реализует связанные объекты, и поэтому вы получаете набор 0. Если вы только что сделали NSSet * mySet = ItemA.ItemB, я уверен, вы увидите, что mySet содержит правильное количество объектов. Но при подсчете ItemA.ItemB отправляется сообщение подсчета в Faulted Set и, таким образом, возвращается 0.

Когда вы используете свойство completeItems, CoreData, кажется, делает что-то, чтобы вернуть вам правильное количество объектов, но не фактические данные объекта.

0 голосов
/ 14 декабря 2011

позволяет использовать эту терминологию:

у нас есть один объект A класса A

у нас есть несколько объектов (безымянных) из ClassB

мы добавили объекты ClassB в objectA.

objectA - это ссылка на подкласс NSManagedObject ... когда вы вызываете objectA.completeItem, вы запрашиваете objectA для набора ItemB, это будет работать, потому что вы работаете с одним экземпляром в памяти.

когда вы создаете новый NSManagedObjectContext и выполняете выборку в нем, он ничего не знает о вашем objectA или его отношениях, если только вы не выполните сохранение контекста objectA перед выполнением выборки.

Редактировать:

для того, чтобы предикат отфильтровывал только объекты classB, принадлежащие ItemA, вы можете использовать предикат наподобие (предположим, что itemA является обратным вашему отношению ItemA cpmletedItem)

[NSPredicate predicateWithFormat: @"itemA = %@",itemA];

...