2015-07-03 84 views
-1

我正在构建一个应用程序,它实现了一个文本输入发生变化时查询数据库的活动文本搜索。 它可以工作,但当NSFetchedResultsController的fetchRequest返回超过一定数量的项目(>〜20)时,键盘输入会很迟钝。NSFetchedResultsController performFetch很慢返回很多项

func textViewDidChange(textView: UITextView) { 
    let predicate = NSPredicate("itemID" > 0) //<- returns all items 
    self.frc.fetchRequest.predicate = predicate 
    self.frc.executeFetchRequest(nil) 
} 

请注意,没有实际的UI更新正在进行,所以laggy键盘输入必须由fetchRequest引起。

有没有一种方法来实现大量项目的实时搜索没有这种滞后?

+0

它接缝你的谓词不会改变。每次按键上的所有项目都有什么用处? – Mundi

+0

示例代码是将问题缩小到仅提取项目的结果。在实际项目中谓词发生变化,UI更新显示新数据 – matteok

+0

一种解决方案是只有在至少有2个字符后才开始读取。 – Mundi

回答

0

问题是,您正在主线程上执行提取操作,并在请求中加载所有对象。你真的需要加载所有的项目吗?作为第一步,设置一个fetchBatchSize只有几个项目实际加载到内存中,当您在视图中滚动时,有些项目会自动加载,其他项目会出现故障。如果这还不够,请考虑设计更改,您应将实际提取移至后台队列,并在结果进入时更新您的用户界面。这是一项重大改变,因为如果用户必须取消先前的正在进行的请求使搜索上下文无效(即他键入一个新字符)。

+0

您能否提供一个关于如何在后台线程上执行提取以及如何取消正在进行的请求的快速示例? – matteok

+0

这不是一个简单的任务,并且需要对功能进行重大更改。将其解释为答案的一部分将需要很长时间。这就是为什么我建议从'fetchBatchSize'开始。 70个对象听起来像一个小尺寸,如果管理得当,实际上会停止主线程。如果您仍然需要努力,我建议您阅读使用父子上下文和“NSOperationQueue”和操作的Core Data多线程。 –

+1

设置fetchBatchSize并不会提高性能,即使设置fetchLimit也会导致我期望设置fetchBatchSize会产生非常类似的效果。 – matteok