UITableView运行时崩溃

时间:2011-07-04 00:21:21

标签: ios uitableview

- (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的标准模式。

我的dataSource很小,它只是一个2节数据集,6行之一,另一行只有2行。关于节中行数和节数的所有方法都已实现。

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

问题是当我减少IB中的UITableView插座尺寸时。如果插座在运行时仅显示第一部分中的2行或3行,则如果向下滚动,应用程序将崩溃。崩溃将发生在第二部分的第一行。只更改以前的情况是IB插座大小,代码中没有任何更改。

控制台中的错误消息是:

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

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

我希望这些(长期)解释足够明确,并为你提供帮助......

干杯, 皮尔

1 个答案:

答案 0 :(得分:1)

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

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

此时,没有为密钥cell设置对象。因此,objectForKey:将返回nil,并且您将在方法结束时返回nil。当您在此处返回'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'时,这就是nil错误的原因。

您不是通过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;
}