【问题标题】:UITableView runtime crashUITableView 运行时崩溃
【发布时间】:2011-07-04 00:21:20
【问题描述】:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];    

NSArray *allSections =[self.tableDataSource allKeys];
NSArray *aSection = [self.tableDataSource objectForKey:[allSections objectAtIndex:indexPath.section]];
NSMutableDictionary *item = [aSection objectAtIndex:indexPath.row] ;

if (cell == nil) {

    /* Trace 1 */
    NSLog(@"Init: Section: %i - Row: %i", indexPath.section, indexPath.row);
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;

    UISwitch *mySwitch = [[UISwitch alloc] init];  
    [mySwitch addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventValueChanged];
    [mySwitch setOn:NO animated:NO];
    cell.accessoryView = mySwitch;
    cell.accessoryView.tag = [[item objectForKey:@"ID"] integerValue];
    cell.textLabel.text = [item objectForKey:@"Name"];
    [item setObject:cell forKey:@"cell"];

} else {

    /* Trace 2 */
    NSLog(@"Done: Section: %i - Row: %i", indexPath.section, indexPath.row);
    cell = [item objectForKey:@"cell"];

}

return cell;} 

大家好,

我正在为 UITableView + 配件苦苦挣扎,该配件在运行时“有时”会崩溃。主要代码 tableView:cellForRowAtIndexPath 就在上面,据我了解,它实际上是基于 UITableView 的标准模式。

我的数据源很小,它只是一个 2 部分数据集,一个 6 行,另一个只有 2 行。实现了所有关于节行数和节数的方法。

IB 中的用户界面具有所需的连接,实际上一切正常。 IB 中的 UITableView 比主视图略小(tableview 下方有 2 个按钮)。当我运行应用程序时,我可以在视图中看到前 6 行(第一部分),但最后 2 行(第二部分)是隐藏的。当然,如果我向下滚动,最后两行会出现...

问题是当我减小 IB 中的 UITableView 插座大小时。如果插座在运行时仅显示第一部分的 2 或 3 行,那么如果我向下滚动,应用程序将崩溃。崩溃将发生在第二部分的第一行。与之前情况唯一变化的是IB outlet size,代码中没有任何变化。

控制台中的错误信息是:

* -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] 中的断言失败,/SourceCache/UIKit_Sim/UIKit-1448.89/UITableView.m:5678 2011-07-04 02:08:46.713 iWiR 客户端 [95362:207] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“UITableView 数据源必须从 tableView:cellForRowAtIndexPath 返回一个单元格:”

如果您查看代码,您会看到有 2 个 NSLog 跟踪。代码的正常行为是“Trace 1”将在控制台中显示为该行的第一个显示,然后,如果我上下滚动,那将是“trace 2”。如果 UITableView 的 IBoutlet “足够大”,就是这种情况,但是,正如我所说,如果我减小插座的大小,即使对于该行的第一次显示,控制台也会显示“Trace 2”。

我希望这些(长)解释足够清楚,并为您提供帮助......

干杯, 皮埃尔

【问题讨论】:

    标签: ios uitableview


    【解决方案1】:

    想象一个有 6 行的表格视图,其中 2 行是可见的。当您向下滚动以将第 4 行移至可见区域时,您从表视图中出列的 cell 将不是 nil,因此将执行 else 子句。

    cell = [item objectForKey:@"cell"];
    

    此时没有为键 cell 设置对象。所以objectForKey: 将返回nil,而单元格将是nil,您将在方法结束时返回。这就是您在此处返回nil 时出现'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' 错误的原因。

    您没有通过UITableView 提供的机制重用单元格。你的方法应该更像,

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSArray *allSections =[self.tableDataSource allKeys];
        NSArray *aSection = [self.tableDataSource objectForKey:[allSections objectAtIndex:indexPath.section]];
        NSMutableDictionary *item = [aSection objectAtIndex:indexPath.row] ;
        UITableViewCell *cell = [item objectForKey:@"cell"];    
    
        if (cell == nil) {
            NSLog(@"Init: Section: %i - Row: %i", indexPath.section, indexPath.row);
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
    
            [..]
        }
    
        return cell;
    }
    

    【讨论】:

    • 你好 Deepak,你是 100% 正确的,我做了改变,当然效果很好!!!真丢人……我本来是专注于IB Size的问题,对代码没有足够的重视……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 2011-07-10
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多