核心数据懒惰地加载对象,并且一旦您尝试引用它们就应该引入任何对象。但是我遇到了这个方案的几个问题。
目标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:方法似乎没有帮助。它似乎不会强制获取附加到获取对象的所有对象树。
在使用对象之前,确保加载对象的最佳方法是什么?为什么快速枚举无法导致加载对象集?
答案 0 :(得分:1)
替换
时会发生什么for (PClip* clip in clips) {
// do something with the clip
}
带
for (PClip* clip in self.clips) {
// do something with the clip
}
?您不能使用像实例变量这样的coredata值,您必须使用setter和getter。因为getter将从核心数据中获取值。
然后尝试为文件名创建一个getter,以便在第一次访问该对象时创建该对象。
根据我的经验,通常没有必要在awakeFromFetch中做任何事情。
答案 1 :(得分:1)
我认为默认情况下会加载托管对象的属性
要加载关系,您可以执行以下操作:
NSArray *relationshipKeys = [NSArray arrayWithObject:@"clips"];
[fetchRequest setRelationshipKeyPathsForPrefetching:relationshipKeys];
答案 2 :(得分:0)
似乎有用(虽然看起来有点像黑客)是强制从顶级对象的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;
}
}
答案 3 :(得分:0)
@CuriousKea只是提示,使用FRC时,不应该在awakeFromFetch中设置关系。因为设置关系将导致FRC再次被通知,并且FRC委托将被调用两次。它伤害了表现。