0

の述語を使用して検索キーワード履歴を実装していUITableViewます。

viewDidLoadでNSMutableArrayオブジェクトを割り当てて初期化します。filteredHistoryこの配列は、検索バーに何かを入力すると ( のTextDidChangeメソッドを使用してUISearchBar) 入力されます。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [self filterContentForSearchText:searchText];
    [self.searchKeywordTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    LogDebug(@"Filtered history count: %d", self.filteredHistory.count);
}

次のようなメソッドを使用してフィルタリングします。

- (void)filterContentForSearchText:(NSString*)searchText
{
    [self.filteredHistory removeAllObjects]; // First clear the filtered array.
    for (MyObject *searchKeyword in self.searchHistory)
    {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                  @"(SELF contains[cd] %@)", searchText];
        [searchKeyword.name compare:searchText options:NSCaseInsensitiveSearch];
        BOOL resultName = [predicate evaluateWithObject:searchKeyword.name];
        if(resultName)
        {
            [self.filteredHistory addObject:searchKeyword];
        }
    }
}

次に、 をリロードUITableViewTextDidChangeます。

tableView numberOfRowsInSection:メソッドで

return self.filteredHistory.count;

私の cellForRowAtIndexPath メソッドには次のものがあります。

LogDebug(@"Current row = %d", indexPath.row);
MyObject search = [self.filteredHistory objectAtIndex:indexPath.row];

次に、数回テストした後、次のエラーでアプリがクラッシュします。

[__NSArrayM objectAtIndex:]: index 10 beyond bounds [0 .. 9]'

私はfilteredHistoryをチェックし、カウントは10です.奇妙なことは、検索バーに同じテキストを入力したときの最初の数回の試みでは問題がなかったということです. 私のデバッグ コードでは、カウントが 10 で、テーブル ビューにインデックス 0 から 9 までのフィルター処理された検索結果が表示されていることがわかりました。コードがスムーズに実行された場合、LogDebug メソッドはインデックス 0 から 9 までの MyObject を出力します。ただし、クラッシュすると、「現在の行 = 10」のみが出力されます。

4

1 に答える 1

2

performSelectorOnMainThreadここでwaitUntilDone:NO

[self.searchKeywordTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

メソッドをすぐに呼び出すのではなく、後で通常の実行ループ処理の一部として呼び出します。したがって、配列をフィルタリングしたcellForRowAtIndexPath、 が呼び出される前にが呼び出される可能性があります。 reloadData

その行を即時の電話に置き換える必要があります

[self.searchKeywordTableView reloadData];
于 2013-07-07T20:21:34.367 に答える