Проблема с загрузкой данных ядра - PullRequest
0 голосов
/ 11 февраля 2011

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

Objective C 2.0 быстрое перечисление объектов в отношении (наборе) может завершиться ошибкой (поскольку объекты в наборе еще не загружены), и функция awakeFromFetch не вызывается до тех пор, пока не будет затронут элемент объекта, управляемого основными данными.

Например, если у меня есть отношение в подклассе NSManagedObject, например:

@property (retain) NSSet* clips;

Сразу после извлечения экземпляра этого объекта, если я попытаюсь использовать быстрое перечисление, такое как:

for (PClip* clip in self.clips) {  
    // do something with the clip  
}

тело цикла никогда не выполняется. В отладчике вы можете видеть, что набор клипов (экземпляр _NSFaultingMutableSet во время выполнения) изначально пуст.

Или, скажем, у меня есть непостоянный член объекта клипа, полученный из постоянного состояния:

@property (retain) NSString* filename

Я синхронизирую это с использованием метода awakeFromFetch, но awakeFromFetch не вызывается до тех пор, пока сначала не будет вызван какой-либо постоянный член объекта, поэтому, если какой-либо код пытается получить доступ к этому непостоянному значению до загрузки объекта, он еще не будет быть определено (то есть будет ноль).

Использование setReturnsObjectsAsFaults: метод в запросе на выборку, похоже, не помогает. Похоже, он не заставляет извлекать все дерево объектов, прикрепленных к извлеченному объекту.

Как лучше всего загружать объекты перед работой с ними? Почему быстрое перечисление не привело к загрузке набора объектов?

Ответы [ 4 ]

1 голос
/ 11 февраля 2011

что происходит при замене

for (PClip* clip in clips) {  
    // do something with the clip  
}

с

for (PClip* clip in self.clips) {  
    // do something with the clip  
}

? Вы не можете использовать значения coredata, такие как переменные экземпляра, вы должны использовать setter и getter. Потому что получатель получит значение из основных данных.

А затем попробуйте создать метод получения имени файла, который создает объект при первом обращении к нему.

Исходя из моего опыта, обычно ничего не нужно делать в awakeFromFetch.

1 голос
/ 31 мая 2012

Я думаю, что свойства управляемых объектов загружаются по умолчанию.
Чтобы загрузить отношения, вы можете сделать что-то вроде этого:
NSArray *relationshipKeys = [NSArray arrayWithObject:@"clips"];<br> [fetchRequest setRelationshipKeyPathsForPrefetching:relationshipKeys];

0 голосов
/ 29 сентября 2015

@ CuriousKea Просто советы, при использовании FRC не следует устанавливать отношения в awakeFromFetch.потому что установка отношения вызовет повторное уведомление FRC, и делегат FRC будет вызван дважды.Вредит производительности.

0 голосов
/ 11 февраля 2011

То, что, кажется, сработало (хотя это выглядит немного хакерски), - это принудительное обход полного дерева объектов из метода awakeFromFetch объекта верхнего уровня.

Например:

-(void) awakeFromFetch {
    // accessing the count of each relationship forces the set of objects to load  
    self.clips.count;  
    for (PClip* clip in self.clips) {  
        // access a persistent member of each object, which will cause
        // its awakeFromFetch method to be called  
        clip.pathURL;    
    }
}
...