过滤巨大的NSArray

Seb*_*ian 4 nsarray nspredicate ios

我正在使用NSPredicate过滤NSArray并将过滤后的数组用于我的UITableView.当用户在UITextField中输入文本时,我正在使用此过滤.因此,每次UITextField中的文本发生更改时,我都会调用我的过滤器函数.

它看起来像这样:

NSArray *hugeArray = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", input];
_resultArray = [hugeArray filteredArrayUsingPredicate:predicate];
[_myTableView reloadData];
Run Code Online (Sandbox Code Playgroud)

当我使用带有大量对象的NSArray时,输入变得非常慢(UI中的完整输入变慢).是否有可能获得更好的性能或在后台运行已过滤的命令?

不应阻止在UITextField中写入内容.当UITableView在输入后很短的时间后刷新它可能没问题.

Rob*_*ier 12

NSPredicate注重灵活性而非速度.对于内存NSArray(即非核心数据关系),通常只需使用循环就可以获得更好的性能.

如果它仍然太慢,那么有几种方法:

  • 合并您的请求.请参阅是否有一种简单的方法(在Cocoa/iOS中)将方法调用排队以在下一个运行循环中运行一次?您可以创建一个合并蹦床,这样您每隔几百毫秒就会更新一次列表.这样,如果用户非常快速地键入,则不会在每个单一的chaacter中重新过滤列表.

  • 更聪明的过滤.如果您只是过滤了"bo"并且您现在想要过滤"bob",那么您知道它是之前列表的子集.您不必重新过滤所有内容.为此编写一个好的算法需要一些工作,但可以显着提高性能.

  • 执行过滤NSOperationQueue(比GCD更容易取消,但GCD也有效),让UI使用KVO注意过滤后的数组何时发生变化.

  • 过滤时跟踪实际更改(添加/删除).reloadData如果可以提供帮助,则不应调用表格视图.您应该执行插入和删除(insertRowsAtIndexPaths:).这可以避免不断搅动细胞,而且通常看起来更好.同样,代码更复杂,但改进可能是戏剧性的.