ios - 过滤巨大的 NSArray

标签 ios nsarray nspredicate

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

看起来像这样:

NSArray *hugeArray = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", input];
_resultArray = [hugeArray filteredArrayUsingPredicate:predicate];
[_myTableView reloadData];

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

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

最佳答案

NSPredicate 侧重于灵 active 而不是速度。对于内存中的 NSArray(即不是 Core Data 关系),通常只需使用循环即可获得更好的性能。

如果还是太慢,那么有几种办法:

  • 合并您的请求。参见 Is there a simple way (in Cocoa/iOS) to queue a method call to run once in the next run loop?您可以创建一个合并蹦床,这样您只会每隔几百毫秒更新一次列表。这样,如果用户输入的速度非常快,您就不会在每个字符都重新过滤列表。

  • 更聪明地过滤。如果您刚刚过滤了“bo”,现在想过滤“bob”,您就知道它是先前列表的子集。您不必重新过滤所有内容。为此编写一个好的算法需要一些工作,但可以显着提高性能。

  • NSOperationQueue 上执行过滤(比 GCD 更容易取消,但 GCD 也可以),并让 UI 使用 KVO 来通知过滤后的数组何时发生变化。

  • 在筛选时跟踪实际更改(添加/删除)。如果可以的话,您不应该在 TableView 上调用 reloadData。您应该执行插入和删除 (insertRowsAtIndexPaths:)。这避免了不断搅动你的细胞,而且它通常看起来也更好。同样,代码更复杂,但改进可能是显着的。

关于ios - 过滤巨大的 NSArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13782263/

相关文章:

iphone - 滚动以在 UIView 中加载内容

ios - 如何快速查询特定对象的 Realm

objective-c - Objective-C 中表示数组的特殊方式

iphone - UITableView 上的核心数据关系和/或 NSPredicate 排序

ios - NSPredicate 带有 !=?

android - Android 和 iOS 推送通知中最多可以显示多少个字符?

ios - 是否可以在拆分模式下为屏幕的全宽在键盘上方创建 inputAccessoryView?

ios - 使用 NSArray 中的数据检查 NSString 的内容

ios - NSArray 或 NSMutableArray 的 removeAllObjects 方法是否释放内存?

iphone - NSPredicate 嵌套关系