- (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”,即使是第一次显示该行。
我希望这些(长期)解释足够明确,并为你提供帮助......
干杯, 皮尔
答案 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;
}