2011-01-09 55 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

相关问题