2011-02-10 179 views
0

核心数据懒惰地加载对象,它应该尽快引入任何对象,只要您尝试引用它们。不过,我遇到了这个方案的一些问题。核心数据延迟加载问题

目的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

今后请花时间适当地格式化问题中的代码(使用“{}”编辑器控件)。 :-) – 2011-02-10 22:22:44

回答

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;  
    } 
} 
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中执行任何操作。

+0

对不起,这只是我的一个遗漏。我编辑了这个问题来解决这个问题。 – CuriousKea 2011-02-12 04:10:40

1

我认为管理对象的属性默认加载。
要加载的关系,你可能会做这样的事情:使用FRC时
NSArray *relationshipKeys = [NSArray arrayWithObject:@"clips"];
[fetchRequest setRelationshipKeyPathsForPrefetching:relationshipKeys];

0

@CuriousKea只是提示,你不应该设置在awakeFromFetch关系。因为设置关系会导致FRC再次被通知,并且FRC委托将被调用两次。它伤害了性能。