【问题标题】:App crashing when it executes the table delegate method应用程序在执行表委托方法时崩溃
【发布时间】:2013-05-17 06:37:58
【问题描述】:

当我在 aepub 阅读器中运行搜索功能时,我的应用程序崩溃了。以index方法进入cellfor行,执行NSLOg(@"%@",hit.neighbourText)时显示异常。

    (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";

        UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }

        cell.textLabel.adjustsFontSizeToFitWidth = YES;

        NSLog(@"indexpath%d",indexPath.row);
        NSLog(@"%@",[results objectAtIndex:[indexPath row]]);

        hit = (SearchResult*)[results objectAtIndex:[indexPath row]];

        if([results count]>0) {
            NSLog(@"%@",hit.neighboringText);
            cell.textLabel.text = [NSString stringWithFormat:@"...%@...", hit.neighboringText];
            cell.detailTextLabel.text = [NSString stringWithFormat:@"Chapter %d - page %d", hit.chapterIndex, hit.pageIndex+1];

           return cell;
        }
    }

我得到了 hit.neighboringText 的一些价值,但在那之后,我重新加载了我的 tableview,然后会引发以下异常,为什么?

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[__NSCFConstantString 相邻文本]:无法识别的选择器发送到实例 0x1481c4' *** 首先抛出调用栈:

【问题讨论】:

  • hit 是什么...很大的可能是它在访问时被 nil/released/deallocated。
  • 在 NSLog(@"%@",hit);检查是否获取 nil 或 SearchResult 对象
  • 可能是hit 不是你的modal object (SearchResult)。尝试打印NSLog("%@", [hit class]);。如果是String,您必须考虑查看您的results 数组。

标签: ios objective-c uitableview


【解决方案1】:

这是因为hit 实际上是一个NSString 对象,而不是您所期望的SearchResult 对象:

hit = (SearchResult*)[results objectAtIndex:[indexPath row]];

线索在异常文本中:

-[__NSCFConstantString neighboringText]: unrecognized selector sent to instance ...
  ^^^^^^^^^^^^^^^^^^^^                   ^^^^^^^^^^^^^^^^^^^^^

SearchResult 的任何转换都不会改变这一点。

编辑:实际上,在您看到演员表的任何地方,您都应该怀疑您正在处理的实际对象。如果您不确定,请通过isKindOfClass: 进行检查。

【讨论】:

    【解决方案2】:

    这意味着 hit = (SearchResult*)[results objectAtIndex:[indexPath row]]; 返回一个 ConstantString 而不是 SearchResult 对象

    最好在从 neighboringText 获取值之前检查 hit 是否与 SearchResult 相同的类类型

    你可以试试这样的:

    if([hit isKindOfClass:[SearchResult Class]]){
      // do something with hit
    }
    else{
    // different class
    }
    

    【讨论】:

    • 另一种方式是 respondsToSelector:
    • 使用 isKindOfClass: 通常表明架构是错误的。不应该存在直到运行时才知道对象类型的情况。
    【解决方案3】:

    你的问题的答案在于错误信息:

    无法识别的选择器发送到实例 0x1481c4。

    接下来您需要做的是通过 po 0x1481c4 打印该地址的值。看起来它实际上不是一个字符串,但您没有显示该代码。

    【讨论】:

      【解决方案4】:

      我猜有两种可能:

      • hit 不是 SearchResult 对象而是 String 对象
      • hitresults 数组不再拥有/已释放,但未设置为 nil 和点垃圾,我相信是这种情况,因为我之前经历过

      我认为您需要确保该数组当时没有自动释放/释放(例如,如果您使用 [NSArray arrayWith...] 创建它,它是自动释放的,您可能不在 cellForRowAtIndexPath 中拥有它)并且命中对象是在将其提供给results 数组之前正确初始化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-13
        • 1970-01-01
        • 2017-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多