2012-06-23 71 views
0

我正在運行一個非常基本的獲取請求,返回大約2000個對象。我使用NSFetchedResultsController與15.爲什麼我所有的NSManagedObjects都會立即出錯?

predicate= [NSPredicate predicateWithFormat:@"ANY tags.tagName==%@", currentTagObject.tagName]; 
    [fetchRequest setPredicate:predicate]; 

    NSSortDescriptor *sort= [[NSSortDescriptor alloc] initWithKey:@"createDate" ascending:NO selector:@selector(compare:)]; 
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]]; 
    [fetchRequest setFetchBatchSize:15]; 
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"createDay" cacheName:nil]; 

一個BATCHSIZE請求花費10秒以上雖然取。我已經啓用SQLite調試,以便我可以看到發生了什麼。我認爲這是獲取所有2000米的實體,只有15與實際值,然後因爲某些原因要通過每一個2000年的目標,並在斷層他們

在取,這些線路出現上千次:

2012-06-22 21:14:47.546 app[9227:707] CoreData: annotation: sql connection fetch time: 0.0107s 
2012-06-22 21:14:47.551 app[9227:707] CoreData: annotation: total fetch execution time: 0.0171s for 15 rows. 
2012-06-22 21:14:47.568 app[9227:707] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE, t0.ZISGLOBAL, t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZCREATEDATE DESC LIMIT 15 
...thousands more lines exactly similar to the three above 

我的表格每次只顯示5個單元格,所以我不知道爲什麼所有對象都立即出錯。什麼可能導致這個?爲什麼所有的對象都會立即出錯,甚至沒有我滾動我的桌子?它是否可以被訪問到某個地方,也許迭代?撥打NSArray *fetchedObjects = fetchedResultsController.fetchedObjects是否會導致所有對象發生故障?

+0

當你取出排序描述符時會發生什麼? –

+0

NSFetchedResultsController獲取需要一個排序描述符。如果我試圖把它拿出來,我會崩潰 – Snowman

+0

我不知道它是否是一種記憶的東西。通過查看select語句,看起來這個對象圖有孩子,並且比簡單的值對象稍微複雜一些。你有沒有嘗試設置includesSubentities爲NO並運行它? – jerrylroberts

回答

0

查了一下它的文檔約batchSize(我的重點)在說:

默認值爲0。0批量大小被視爲無窮大,即禁用批次斷裂行爲。

如果設置非零批處理大小,執行提取時返回的對象集合會分解爲批處理。當執行提取時,評估整個請求並記錄所有匹配對象的身份,但是不會超過batchSize對象的數據將從持久存儲時間提取。從執行請求返回的數組將是一個代理對象,它可以按需透明地批次錯誤。 (數據庫而言,這是內存遊標。)

您可以使用此功能來限制應用程序中數據的工作集。結合fetchLimit,您可以創建任意結果集的子範圍。

所以,很明顯,根據這個解釋,你會得到2000/15次往返商店。這肯定需要一些時間。你需要所有的數據,因爲你的排序和ANY謂詞,但你指示的請求一次只能得到15。

此外,爲了完整起見,請從以前的評論中刪除您的排序描述符中的compare

+0

我明白了這一點,但沒有人回答的問題是,雖然需要2000/15往返,但是在執行請求時不應該立即執行所有這些往返操作?數據訪問時應執行每次往返。目前所有這些往返行程都是在最初的抓取過程中發生的,因此對於2000年的結果,請求需要10秒以上。這不可能是典型的,可以嗎? – Snowman

+0

我不明白你的反對意見。聲明「執行請求時,不應該立即執行所有這些往返行程。」是錯誤的。想想吧... – Mundi

+1

我想出了這個事情發生的原因。請參閱http://stackoverflow.com/questions/11170762/dynamic-uitableview-height-with-core-data-objects – Snowman

0

您看到的行爲在「核心數據編程指南」中的Batch-faulting and Pre-fetching段落中有很好的描述。

總之,如果您使用謂詞來獲取具有特定名稱標籤的對象,則應該預取標籤對象。這是因爲通常在讀取對象時,Core Data不會獲取相關對象,而是使用故障代替。現在你的謂詞觸發器單獨發射那些緩慢的故障。

相關問題