在 TableView 上执行搜索后应用程序崩溃

Posted

技术标签:

【中文标题】在 TableView 上执行搜索后应用程序崩溃【英文标题】:App crashes after performing search on TableView 【发布时间】:2012-11-16 14:31:44 【问题描述】:

我目前正在尝试按照本教程实施搜索。 http://www.appcoda.com/how-to-add-search-bar-uitableview/ 但是,我的应用程序崩溃了,但我不知道如何修复它。

我的应用程序中的 JSON 目前只有一行的数据(我无法更改它,因为我没有数据库访问权限)。

我的初始视图看起来不错。 TableView 已填充(有 1 行)。当我点击搜索栏并输入一些不在该项目名称中的字符时,我会看到正常的“未找到结果”屏幕。 当我输入项目名称中存在的任何字符时,它会按预期显示过滤的项目。但是,当我输入第二个字母(即项目名称)时,我的应用程序崩溃,并在控制台中给出以下输出。

Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (1)'

现在看我的代码。 numberOfRowsInSection 方法根据搜索进行修改。

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    // Return the number of rows in the section.
    if (tableView == self.searchDisplayController.searchResultsTableView) 
        return [searchResults count];


     else 
        return [[resultSearch valueForKeyPath:@"data.auctions"]count];
        

numberOfSectionsInTableView 只有一个部分硬编码(返回 1;因为我目前不需要更多)

现在我的 cellForRowAtIndexPath:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    

        static NSString *simpleTableIdentifier = @"SimpleTableItem";
        SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; //custom cell

        if (cell == nil)
        
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell" owner:self options:nil];
            cell = [nib objectAtIndex:0];

        


        NSDictionary *aucdict = [jsonAukResultsSearch objectAtIndex:indexPath.row]; //assigning current row from NSMutableArray(jsonAukResultsSearch) to Dictionary, this is probably crash spot
        NSURL *imageURL = [NSURL URLWithString:[aucdict objectForKey:@"img_url"]];
        NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
//sending request to get picture
        UIImage *imageLoad = [[UIImage alloc] initWithData:result];
        NSString *timeString = [aucdict objectForKey:@"time_left"];
        NSString *priceString = [aucdict objectForKey:@"current_value"];


        // Configure the cell...
        if (tableView == self.searchDisplayController.searchResultsTableView) 
            cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
         else 
            cell.nameLabel.text = [aucdict objectForKey:@"name"];
        

        //cell.thumbnailImageView.image = imageLoad;
        //commented while crashes are happening


        return cell;
    

现在,在我的应用程序崩溃后,我与

NSDictionary *aucdict = [jsonAukResultsSearch objectAtIndex:indexPath.row];

是荧光笔,所以我想,这可能是 indexPath 参数超出范围的地方。我真的不明白 index(1) 怎么会越界(1)。我知道,我只有零个或一个返回行(取决于搜索短语)。

我今天才开始搜索,所以我不知道那些棘手的地方是什么..任何建议都非常感谢:)谢谢你,Yanchi

编辑:好的,所以我发现我的问题可能出在哪里......我密切关注这个问题顶部提到的教程。这个方法应该返回带有搜索结果的数组。

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope


    NSPredicate *resultPredicate = [NSPredicate
                                    predicateWithFormat:@"SELF contains[cd] %@",
                                    searchText];

    searchResults = [poleMien filteredArrayUsingPredicate:resultPredicate];
    NSLog(@"%u",[searchResults count]);

如您所见,我添加了 NSLog... 现在,当我添加匹配的第一个字母时,控制台输出为 1(应该是),因此我的过滤结果将毫无问题地显示。但是,当我输入另一个匹配的字母时,我的 searchResults 数组将增加到 2(好像它会计算“匹配”字母),这可能是我崩溃的原因(尝试访问索引 1,而我只有一个的数据我的 searchResults 数组中的项目)

之后我更改了我的 NSLog 以显示数组的内容...插入匹配的字母后,相同的项目被添加到我的数组中(所以我的数组中有另一个项目,它与我的数组中的第一项具有相同的数据)

编辑 2:好的,我的问题是,每当我将 json 数据从字典保存到数组时(这样我就可以使用数组来过滤结果),我在 cellForRowAtIndexPath 中执行此操作。所以我的数组每个都加载相同的值时间,搜索表被“重新填充”。现在我需要找到一些方法将数据加载到数组中,只有当它是不同的项目时。

【问题讨论】:

好吧,index(1) 超出了 bounds(1) 的范围,因为其中只有一个元素的 NSArray 应该只有 index(0) 处的元素。所以发生的事情是,当只有一个元素(在索引 0 处)时,表视图正在向其数据源询问 /second/ 元素(索引 1)。如果表视图知道只有一行,则不应这样做。您能否在程序中的某处设置断点并查看您的 tableview 为 -[UITableView numberOfSections] 和 -[UITableView numberOfRowsInSection:] 返回的内容,看看它们是否是您期望的值? 我的问题是,我不确定在哪里设置断点......在我有机会在 searchBar 中实际放置一些东西之前会到达断点(那是因为我的所有项目的表格视图都会被加载事先。我试图 nslog 这些计数,但控制台中没有显示任何内容 我想我已经接近解决这个问题了...我的 - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope 在我添加字母时用更多索引填充我的数组搜索栏 用那个方法更新我的问题 另一个更新..错误的字段填充 【参考方案1】:

好吧,我终于发现出了什么问题。我正在将 json 响应的名称字段保存到数组中。我的数组正在 cellForRowAtIndexPath 中更新,因此在搜索框中输入两个与我的结果匹配的字母后,该结果被保存到数组中两次(所以我的数组中有 2 个相同的项目)因此我崩溃了,因为索引超出了界限.

我通过检查我的数组是否包含相同的值并将唯一值保存到另一个这样的数组中来修复它。

newarray = [[NSMutableArray alloc] init];
    NSString *laststring = nil;
    for (NSString *currentstring in poleMien)
    
        if (![currentstring isEqualToString:laststring]) [newarray addObject:currentstring];
        laststring = currentstring;
    

谢谢browsoffire,你告诉我正确的方法:)

【讨论】:

以上是关于在 TableView 上执行搜索后应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

修改 XIB 文件后应用程序崩溃

如何在更新 tableview 时使用搜索栏对我的 NSFetchedResults 数据进行排序,而不会在 fetchedRC.performFetch() 上崩溃?更新

TableView 中的搜索栏:输入搜索文本字符串的最后一个字符时应用程序崩溃

在快速键入期间使用搜索栏进行搜索时 TableView 崩溃

Tableview拖到底部时导致应用程序崩溃

TableView 由于核心数据错误而崩溃/冻结