Skip to main content
 首页 » 编程设计

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

2025年12月25日31bjzhanghao

我目前正在尝试通过遵循本教程来实现搜索。
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中执行。表已“重新填充”。现在,我需要找到某种方法,仅当数据是不同的项目时才将数据加载到数组中。

请您参考如下方法:

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

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

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

谢谢eyebrowsoffire,您给我展示了正确的方法:)