0

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

我将其与 using awakeFromFetch 方法同步,但直到第一次调用对象的某个持久成员后才会调用 awakeFromFetch,因此如果某些代码在加载对象之前尝试访问此非持久值,则尚未定义(即为零)。

在获取请求上使用 setReturnsObjectsAsFaults: 方法似乎没有帮助。它似乎不会强制获取附加到所获取对象的所有对象树。

确保在使用对象之前加载对象的最佳方法是什么?为什么快速枚举无法导致对象集加载?

4

4 回答 4

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 中做任何事情。

于 2011-02-11T08:31:40.453 回答
1

我认为托管对象的属性是默认加载的。
要加载关系,您可以执行以下操作:
NSArray *relationshipKeys = [NSArray arrayWithObject:@"clips"];
[fetchRequest setRelationshipKeyPathsForPrefetching:relationshipKeys];

于 2012-05-31T12:43:10.900 回答
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;    
    }
}
于 2011-02-10T22:28:27.000 回答
0

@CuriousKea 只是提示,使用 FRC 时,不应在 awakeFromFetch 中设置关系。因为设置relationship会导致FRC再次被通知,FRC delegate会被调用两次。它会损害性能。

于 2015-09-29T16:14:39.823 回答