表视图返回有趣的错误

时间:2012-06-03 00:18:19

标签: iphone objective-c ios xcode cocoa-touch

好的我正在使用目标c创建表视图,但数据源无法正常工作......

我的错误:

2012-06-02 20:14:39.891 Dot Golf Scoring[195:707] *** Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:], /SourceCache/UIKit/UIKit-1914.85/UITableView.m:6061
2012-06-02 20:14:39.895 Dot Golf Scoring[195:707] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

我的代码:

-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 16;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return @"Comments On Your Round";
}

-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

    cell.textLabel.text = @"Text Label";

    return cell;
}

为什么表格视图没有填满这些假数据???

2 个答案:

答案 0 :(得分:7)

你永远不会初始化细胞。使用此代码:

    - (UITableViewCell *)tableView:(UITableView *)tableView2 cellForRowAtIndexPath:(NSIndexPath *)indexPath 

{


    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:@"UITableViewCell"];


    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:@"UITableViewCell"]
                autorelease];


        cell.textLabel.text = nil;                


    }

    if (cell) {

        //customization 
        cell.textLabel.text = @"Text Label";
    }

    return cell;
}

你说你是个菜鸟....让我解释一下 首先尝试拿起这本书:

The Big Nerd Ranch Guide

你在想什么是出队基本上正在初始化?没有!出列基本上是任何不可见的单元格,也就是你滚过它。因此,cell == nil可能会在四种情况下被调用(我能想到):

  1. 当我们第一次设置表格视图时(单元格将为零)
  2. 当我们重新加载数据时
  3. 每当我们到达这个班级时
  4. 当单元格从表格视图中不可见时
  5. 因此,出列的标识符就像一个ID。然后在语句中查看cell是否为nil,我们初始化cell,您可以看到被覆盖的init方法:initWithStyle。这就是cell的类型,有不同的类型,可以自定义不同的变量。我给你看了默认值。然后我们使用reuseIdentifier这是我们之前说过的出列标识符。他们必须匹配!我只需textLabel来获得更好的结构,在这种情况下,每个单元格都有相同的文本,所以它无关紧要。它使得出列的单元格能够通过您实现的正确定制而返回。一旦单元格实际有效,我们就可以自定义。

    此外,您对每个单元格使用相同的文本。如果您确实希望每个单元格都有不同的文本,请熟悉NSArray。然后,您可以在count中提供数组numberOfRowsForSection,然后执行以下操作:

    cell.textLabel.text = [array objectAtIndex: [indexPath row]];
    

    其中indexPathNSIndexPath方法中提供的cellForRowAtIndexPath参数。 row变量是row数字,所以一切都适合!

    哇,这真是太多了! 现在停止成为一个客观的菜鸟并开始阅读一些书籍!

    欲了解更多信息,请阅读:

    Table View Apple Documentation

答案 1 :(得分:3)

我认为您不会阅读Table View Programming Guide或了解UITableViews的重用机制;)

UITableViews中的单元格被重用/回收,以避免每次需要单元格时重新分配UITableViewCell类的实例。这是因为UITableView需要很多反应,特别是在滚动tableview时需要快速滚动,并且每次分配一个新的UITableViewCell实例会使tableview在创建实例时挂起一秒钟。

因此,UITableViewCell重用机制背后的想法是来分配最少量的单元格,并且每次需要单元格时,尝试重用/回收先前已分配但不再是用户的单元格(因为你滚动后它是在屏幕外)。 但是如果没有可供重用的单元格,则需要自己分配一个!。 您忘记在代码中执行此部分,这就是您最终返回nil单元格的原因,该单元格会抛出异常。


所以执行此操作的典型代码是:

static NSString* kCellId = @"Cell";
// First, try to reuse a cell that was previously allocated
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:kCellId];

// here, if a cell is returned, that means that we have an old cell
// that was used before but is no longer onscreen (so we can recycle it
// and just actualize its content)
// but if cell is nil, this means the UITableView didn't have a cell available to reuse
// so we need to create a new one
if (cell == nil)
{
   // So if we didn't have a old cell ready to reuse that have been returned, create one
   cell = [[[UITableViewCell alloc] initWithReusableIdentifier:kCellId] autorelease];
   // And configure every properties of the cell that will be common to every cell
   // and won't change even if the cell is recycled, eg:
   cell.textLabel.textColor = [UIColor redColor];
   cell.textLabel.font = [UIFont boldSystemFontOfSize:12];
   // etc
}
// And at this point, we have a cell, either newly created or that have been recycled
// So we configure every property that is row-dependant and change for each row, eg:
cell.textLabel.text = [myTextsArray objectAtIndex:indexPath.row];

注意:我从未使用过故事板而是AFAIK,当你使用故事板时,你不需要有“if”语句并在没有可重复使用的单元格时创建单元格,因为故事板会为你创建它在故事板中使用单元格设计。但是,这是您不需要自己分配单元格的唯一情况。