2011-04-14 88 views
8

我遇到的問題如下:核心數據:背景讀取,NSFetchedResultsController和排序時間

我有一個UITableView我與從NSFetchedResultsController圍繞從核心數據6000點的行中檢索數據饋送。 NSFetchRequestfetchBatchSize設置爲20,如果我不應用任何NSSortDescriptor,則提取速度足夠快,不會阻塞UI線程。

不過,我確實需要顯示的字母順序排序那些行我用下面的NSSortDescriptor:

[[[NSSortDescriptor alloc] initWithKey:@"optionText" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease]; 

這裏是當事情發生變化,提取操作現在只需3秒左右才能完成,因爲6000行正在排序。很明顯,在這段時間內,用戶界面被阻止,用戶體驗很糟糕。

我知道我可以在後臺線程中執行取指操作,然後將對象ID傳遞給主線程,但是在那種情況下,我仍然可以在主線程中使用NSFetchedResultsController(我也正在使用它來觀察數據變化)?

我也有indexed我排序的屬性,但只優化查找和排序性能。

任何想法將不勝感激,謝謝!

+0

愚蠢的問題,但我想你不能預先對數據進行排序,然後再將其加載到核心數據? – 2012-02-08 11:44:16

+0

愚蠢的問題,在您運行提取請求時,managedObjectContext.hasChanges的值是什麼? – Drew 2013-01-25 06:53:24

回答

0

首先 '批量導入'所有的NSFetchedResultsController通常在主線程中使用。並且它至今不支持後臺獲取Apple發佈iOS 6.

因此,當您調用NSFetchedResultController的performFectch時,您必須「阻塞」主線程一段時間。但是我們希望時間很短。

(只要我能記得,你必須設置一個排序描述符NSFetchedResultController,所以我不知道你是怎麼做,而不是設定一種描述它。看看類的引用)

我不確定您是否使用Sqlite Store。如果是這樣,我幾乎不能相信你的排序描述符工作。 (看看核心數據編程指南:故障排除部分)。如果不是這樣,那麼在內存中保存這麼多數據將不是一個好主意

最後我們達到了它爲什麼速度慢的地步。使用「localizedCaseInsensitiveCompare:」這種排序使得你的讀取緩慢,因爲比較Unicode字符串會很慢。 (在WWDC 2010 Core Data Performance on iPhone中提到)。

與許多其他應用程序一樣,您應該根據您的「optionText」創建非Unicode字符串字段/屬性,並根據該非Unicode字符串屬性進行排序。

+1

任何人都可以解釋投票嗎? – 2012-11-20 03:43:39

-4

您是否嘗試過運行performFetch:在後臺方法,無論是與

[controller performSelectorInBackground:@selector(performFetch) withObject:nil]; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    [controller performFetch]; 
}); 
+1

這不是一個安全的解決方案。 NSFetchedResultsController有一個不是線程安全的managedObjectContext。 – 2011-06-13 10:11:25

+0

我同意@Tal Bereznitskey。任何其他想法? – monchote 2011-06-15 12:13:36

0

使用緩存可能會幫助,以獲得更好的性能。

我得到了同樣的問題,並意識到在第一次調用時,獲取需要超過3秒鐘,但執行兩次提取時,會立即顯示其結果。

+0

是的,緩存有助於後續的抓取,但第一個緩存仍然非常緩慢,明顯阻塞了UI線程。 – monchote 2011-08-13 18:27:17

0

在一張表中顯示6000行可能不是用戶體驗方面的最佳解決方案。也許你應該在之前添加一個過濾器表。類似於地址簿中的組。如果您設法將每個過濾器選項的行數減少到更易於管理的數量,那麼這可能會帶來更好的用戶體驗。這將減少加載時間和滾動時間。

我不知道你顯示什麼樣的數據,所以也許沒有辦法,只能在一個長列表中顯示所有數據。對於人來說,你可以添加性別和年齡段的選項。對於汽車,你可以添加一個品牌和型號的過濾器....

+0

我知道這不是最好的UI設計,但它是一項要求,客戶不願意改變它。我真的認爲NSFetchedResultsController應該支持後臺提取。儘管感謝您的評論。 – monchote 2011-08-11 16:48:47

3

如何使用NSFetchRequest的batchSize屬性?

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

1

我在使用單獨的NSManagedObjectContext的NSOperation中執行背景批量導入。我定期保存第二個上下文,它會觸發一個通知來更新我的NSFetchedResultsController所連接的主NSManagedContext。

也許類似的技術可以應用到你的抓取

這裏是可可是我關於它的女朋友文章:

http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/

,並在核心數據編程指南還提到技術

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174-SW1

相關問題