2011-02-10 129 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委託將被調用兩次。它傷害了性能。