2011-01-09 54 views
8

一直在尋找高和低這樣的:核心數據:中斷執行NSFetchRequest

在覈心數據,有沒有辦法打斷/停止/取消和執行NSFetchRequest?我正在嘗試優化它的各種方法,但它不夠(我有42,000條記錄),所以我必須在NSOperation中運行它。當輸入一個新字符時,我需要取消先前的fetchRequest,但是[nsoperation cancel]不做任何事情。

另一種方法可能是將我正在搜索的字段移動到其他可中斷索引,可能是內存中,也可能是單獨的sqlite3數據庫,這似乎是sqlite_interrupt可中斷的。

回答

2

我的解決方案是讓查詢操作繼續運行,但要在發送事件更新UI之前檢查它們是否被取消。

這並不完美,因爲您仍然可以運行很多查詢操作,其結果永遠不會被使用,但它仍然快得多。

2

簡短的回答 - 不,不直接,對不起。

朗的答案 - 是的,但你必須做相當多的工作,或做

您需要在後臺線程中運行它(這聽起來像你通過的NSOperation正在已經在這樣做)

在您的抓取中,將限制設置爲一次獲得20個結果並在循環中運行。每次通過循環時,將獲得的結果添加到數組中。每次獲取獲取每組結果時,請檢查是否要取消請求。

+2

後者不起作用,因爲對於一個有序查詢,獲得前20個頭花費的時間幾乎是相同的。 – mclin 2011-06-06 14:26:59

1

我其實和你有同樣的問題。要解決它我使用performSelector:afterDelay:方法

這有點棘手,但當用戶快速鍵入快速3個字母我不想發送3個請求,但只有一個時,用戶完成打字。我設置了0.5或更多的小延遲。

,並使用此代碼:

[NSObject cancelPreviousPerformRequestsWithTarget:self]; 
[self performSelector:@selector(fetchSearch:) withObject:searchQuery afterDelay:0.5]; 

如果用戶輸入速度快,將取消之前的請求和發送只有最後一個。

14

直接回答你的問題是沒有。用你目前的設計,你最好的選擇是在手術中做到這一點,但你有線程障礙擔心並放慢你的速度。請記住,如果您的操作沒有在主線程上運行,那麼您需要單獨運行NSManagedObjectContext,否則您將遇到線程問題。

更好的問題:爲什麼你要爲每個角色做一個新的提取?

如果您已經擁有先前搜索的提取結果,並且用戶沒有刪除某個字符,只需將現有結果與針對NSArray的謂詞運行即可。這將進一步優化搜索,而不是每次都進入磁盤。由於它在內存中會非常快速。

  • 只在磁盤上的第一個字符
  • 命中磁盤只有一個字符從搜索框
  • 考慮預裝刪除命中:

    實施搜索字段時,請考慮以下選項objectID和可搜索屬性以避免磁盤命中。

根據您正在搜索的內容(還有一些方法可以重新規範化Core Data存儲以改進搜索),您可以預先加載很多內容。即使有42K記錄,如果搜索屬性足夠小,您可以將它們全部加載到內存中。

無論如何,如果用戶開始按「A」,您需要測試該用例的機會。

NSFetchRequest的什麼部分很慢?打到SQLite數據庫或將數據加載到內存中?根據您的答案,您可以直接提高搜索性能。

+0

輝煌,謝謝! – JOM 2013-12-20 12:32:53

相關問題