2

如果我这样做,我的应用程序会崩溃:

  1. 我在我的 UITableView 上进行搜索

  2. 搜索后,我点击 UITableView 的searchDisplayControllerUITableViewCell 并转到另一个视图控制器

  3. 然后我回到主 UITableView——questionTable我在其中搜索的那个,然后点击最后一个单元格,或者任何大于我之前搜索结果数量的单元格。

  4. 应用程序因此错误而崩溃:

    *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 12 beyond bounds [0 .. 0]'
    *** First throw call stack:(0x35aa188f 0x37e48259 0x359ea9db 0x155fd 0x3384df5b 0x153ed 0x3358793d 0x33601627 0x355bb933 0x35a75a33 0x35a75699 0x35a7426f 0x359f74a5 0x359f736d 0x37693439 0x33503cd5 0x95a3 0x9548) terminate called throwing an exception(lldb) 
    

我怀疑问题出在我的代码上,因为搜索 UITableView 对我来说是一个新话题。我就是这样做的:

1.我的VC符合这些协议<UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>

2.我有这些变量:

@property (nonatomic, retain) NSMutableArray *searchResults;
@property (nonatomic, copy) NSString *savedSearchTerm;

3. 在viewDidLoad我设置我搜索的 UITableView 的来源:

    self.questionList = [[NSArray alloc]
                     initWithObjects: MY OBJECTS HERE, nil];

if ([self savedSearchTerm])
{
    [[[self searchDisplayController] searchBar] setText:[self savedSearchTerm]];
}

4.我有这个动作来处理搜索:

- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];

if ([self searchResults] == nil)
{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [self setSearchResults:array];
}
[[self searchResults] removeAllObjects];

if ([[self savedSearchTerm] length] != 0)
{
    for (NSString *currentString in [self questionList])
    {
        if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
        {
            [[self searchResults] addObject:currentString];
        }
    }
}   
}

5) 以下是我设置 UITable 视图的方式:

    (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
    NSInteger row = [indexPath row];
    NSString *contentForThisRow = nil;

    if (tableView == [[self searchDisplayController] searchResultsTableView])
        contentForThisRow = [[self searchResults] objectAtIndex:row];
    else
        contentForThisRow = [[self questionList] objectAtIndex:row];

    static NSString *CellIdentifier = @"questionsCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    [[cell textLabel] setText:contentForThisRow];
    return cell;
    }

6)这是我的numberOfRowsInSection方法的样子:

(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows;

if (tableView == [[self searchDisplayController] searchResultsTableView])
rows = [[self searchResults] count];
else
rows = [[self questionList] count];
return rows;
}

7)最后,我有这两种方法:

(BOOL)searchDisplayController:(UISearchDisplayController *)controller 
shouldReloadTableForSearchString:(NSString *)searchString
{
    [self handleSearchForTerm:searchString];
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

(void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
    [self setSavedSearchTerm:nil];
    [[self questionTable] reloadData];
}

对于这个冗长的问题,我真的很抱歉。我在代码中犯了一些错误,我希望有人能告诉我正确的方法。搜索栏控制器已在 IB 中正确链接任何帮助将不胜感激!

新编辑: 我正在推动一个新的 VC didSelectRowAtIndePath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"toAnswer" sender:indexPath];
}

我正在那里更新一个 NSString 。当我只使用一个 TableView 时它工作得很好

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    ((QandADetailsViewController *)segue.destinationViewController).delegate=self;

    NSIndexPath *indexPath = (NSIndexPath *)sender;

    QandADetailsViewController *mdvc = segue.destinationViewController;

    if (self.searchResults == nil) {
        mdvc.questionName = [self.questionList
                             objectAtIndex:indexPath.row];
    } else {
        mdvc.questionName = [self.searchResults
                             objectAtIndex:indexPath.row];
    }
}
4

2 回答 2

3

在为 segue 做准备时,对 searchResults == nil 的检查可能不正确。没有理由期望在第一次搜索后它会为零。这意味着您将始终在后续表选择中取消引用搜索数组,从而解释索引超出范围。

我认为,解决方法是询问if ([self.searchDisplayController isActive])搜索结果是否存在。

于 2012-08-24T14:08:36.587 回答
1

看来您的数组是空的。

我建议您在执行每个步骤后记录您的阵列,这样您就可以看到它在哪里变空。

还记录行号和方法名称,请参阅此,如何记录:

NSLog(@"%s\n [Line: %d]\n  array:%@\n\n", __PRETTY_FUNCTION__, __LINE__, yourArray);
于 2012-08-24T08:00:38.920 回答