核心数据:中断执行NSFetchRequest

时间:2011-01-09 09:10:19

标签: iphone search core-data

为此寻找高低:

在核心数据中,有没有办法中断/停止/取消和执行NSFetchRequest?

我正在iPhone应用程序中实现增量搜索,我已经尝试过优化它的各种方法,但这还不够(我有42,000条记录),所以我必须在NSOperation中运行它。键入新字符时,我需要取消之前的fetchRequest,但[nsoperation cancel]不执行任何操作。

另一种方法可能是将我正在搜索的字段移动到其他可中断的索引中,可能在内存中,或者可能是一个单独的sqlite3数据库,它似乎可以用sqlite_interrupt中断。

4 个答案:

答案 0 :(得分:14)

你问题的直接答案是否定的。您最好的选择,当前的设计是在操作中执行它们,但是您有线程障碍来担心并减慢您的速度。请记住,如果您的操作没有在主线程上运行,那么您需要单独的NSManagedObjectContext进行操作,否则您将遇到线程问题。

更好的问题:为什么要对每个角色进行新的抓取?

如果您已经拥有上一次搜索的抓取结果且用户未删除某个字符,则只需获取现有结果并针对NSArray运行谓词。这将进一步细化搜索,而不是每次都进入磁盘。因为它在内存中会非常快。

实施搜索字段时请考虑以下选项:

  • 仅在第一个字符
  • 上点击磁盘
  • 仅在从搜索框中删除字符时点击磁盘
  • 考虑预加载objectID和searchable属性以避免磁盘命中。

根据您搜索的内容(以及重新规范Core Data存储以改进搜索的方法),您可以在内存中预加载相当多的内容。即使有42K记录,如果搜索属性足够小,您也可以将它们全部加载到内存中。

如果用户按“A”开始,您仍然需要测试该用例。

NSFetchRequest的哪一部分很慢?点击SQLite数据库还是将数据加载到内存中?根据您的回答,您可以直接提高搜索效果。

答案 1 :(得分:3)

我的解决方案是让查询操作继续运行,但要在发送事件以更新UI之前检查它们是否已被取消。

这并不完美,因为你仍然可以运行大量的查询操作,结果永远不会被使用,但它仍然要快得多。

答案 2 :(得分:2)

简短回答 - 不,不是直接,抱歉。

答案很长 - 是的,但你必须做很多工作或努力做到这一点

您需要在后台线程中运行它(听起来您已经通过NSOperation进行了操作)

在您的提取中,设置限制以一次获得20个结果并在循环中运行它。每次循环时,将其获得的结果添加到数组中。每次获取每组结果时,请检查是否要取消请求。

答案 3 :(得分:2)

我实际上和你有同样的问题。要解决它,我使用performSelector:afterDelay:方法

这有点棘手,但当用户快速输入3个快速字母时,我不想发送3个请求,但只有一个用户完成输入时才发送。我设置了0.5或更长的小延迟。

并使用此代码:

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

如果用户快速输入,它将取消之前的请求并仅发送最后一个请求。