为什么Apple的TheElements示例中的cellForRowAtIndexPath中没有返回的单元格nil?

时间:2015-01-13 02:33:05

标签: ios uitableview

我知道这个问题可能看起来有点奇怪,但是我看着Apple的例子TheElements,并注意到他们cellForRowAtIndexPath的实现甚至没有检查出队的单元格是否为零。

如果您刚刚获得最新版本的TheElements示例,那就不是我所指的那个。您必须将dequeueReusableCellWithIdentifier:forIndexPath:替换为旧版本,即dequeueReusableCellWithIdentifier

这就是为什么我希望最初出列的单元格为零:
来自dequeueReusableCellWithIdentifier: ...的Apple文档 此方法使现有单元格可用,如果有可用单元格,或使用先前注册的类或nib文件创建新单元格。如果没有单元可供重用,并且您没有注册类或nib文件,则此方法返回nil。

但是,我通过调试器运行它,发现第一次调用该方法时,返回的单元格有一个值。

然而,在我UIViewController的简单实施中,已经出列的单元格最初为零,直到它们被回收,正如Apple文档所解释的那样。

修改

在收到答案并将其检出后,没有nil单元格出列的原因很明显:该示例使用了一个故事板,其中表视图控制器包含一个原型单元格。

这是我的实现,它检查单元格是否为零。

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

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
                                      reuseIdentifier:CellIdentifier];
    }

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

    return cell;
}

而且,这是示例中的实现,TheElements:

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

    AtomicElementTableViewCell *cell =
        (AtomicElementTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"AtomicElementTableViewCell"];

    // set the element for this cell as specified by the datasource. The atomicElementForIndexPath: is declared
    // as part of the ElementsDataSource Protocol and will return the appropriate element for the index row
    //
    cell.element = [self atomicElementForIndexPath:indexPath];

    return cell;
}

2 个答案:

答案 0 :(得分:1)

  

然而,在我简单的UIViewController实现中,出列的单元格最初为零,直到它们被回收为止

所以,有点历史。

  • iOS 4 之前和之前,您调用dequeueReusableCellWithIdentifier:来获取您的单元格。最初的细胞都是零,直到你有足够大的堆来开始回收它们。因此,你需要检查nil并自己创建初始的细胞堆。

    这就是你正在做的事情。

  • iOS 5 中,介绍了故事板。使用故事板的一大优势是它可以作为细胞的来源。因此,dequeueReusableCellWithIdentifier:,如果与故事板中的标识符匹配的标识符一起使用,永远不会返回nil。

    这就是元素在您引用的代码中所做的事情。

  • iOS 6 dequeueReusableCellWithIdentifier:forIndexPath:。这使得故事板在iOS 5中所做的事情发生始终。通过注册单元类或nib以通过将单元标识符与故事板中的标识符相匹配将其绑定到标识符,可以配置表,以便在调用dequeueReusableCellWithIdentifier:forIndexPath:时, 如果需要新单元,则生成新单元格。因此,细胞永远不会是零。

    这是你应该做的事情。您可以使用表格为您的小区标识符注册UITableViewCell;然后用这个单元格标识符调用dequeueReusableCellWithIdentifier:forIndexPath:,看哪,单元格永远不会为零。

顺便说一下,我们现在已经是iOS 8了。所以你所做的不仅仅是过时了 - 它已经过了四代了。

答案 1 :(得分:0)

您可以学习以下两种方法。

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

使用故事板时,tableview会注册一个nib或sth,就像一个带有特殊标识符的nib,你也可以在单元格的xib片段中自定义一个标识符。

如果使用代码创建tableview,可以在vc的viewDidLoad方法中注册一个单元格类。

然后你总是可以在tableview的回调中使用你注册的标识符将一个单元格出列。