Ios 了解UITableView dequeueReusableCellWithIdentifier-即使在第一次调用时也返回单元格

Ios 了解UITableView dequeueReusableCellWithIdentifier-即使在第一次调用时也返回单元格,ios,objective-c,uitableview,Ios,Objective C,Uitableview,我很难理解这是怎么回事。我读过很多关于它的文章,比如和 但是,我的UITableView每次都会成功地将单元格出列(它永远不会为零),即使在第一次加载时也是如此。我的印象是,类似的单元格应该使用相同的标识符,因此您只需更改必要的内容 因为 if (!cell) { NSLog(@"New cell"); cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];

我很难理解这是怎么回事。我读过很多关于它的文章,比如和

但是,我的UITableView每次都会成功地将单元格出列(它永远不会为零),即使在第一次加载时也是如此。我的印象是,类似的单元格应该使用相同的标识符,因此您只需更改必要的内容

因为

if (!cell) {
    NSLog(@"New cell");
    cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}
从未被调用,我不确定如何处理同一表格中具有不同样式的单元格,因为只能在初始值设定项中设置样式

我还尝试使用不同的单元格标识符,以确保它不会重用来自不同表或其他地方的单元格。我正在将这些标识符注册到
[tableView registerClass:forCellReuseIdentifier:

如果我理解的话,这个方法应该只返回以前创建的已经移出屏幕的单元格(隐藏,即可以重用)。那它第一次调用时怎么会返回一个单元格呢


编辑:因此混淆是使用了
[tableView dequeueReusableCellWithIdentifier:forIndexPath:
而不是
[tableView dequeueReusableCellWithIdentifier:][/code>(第一个需要注册标识符,如果没有可用的标识符,第二个将返回nil,这是我在上面所期望的行为)

但是,我注意到,当我将代码更改为使用
[tableView dequeueReusableCellWithIdentifier:
时,它创建了一个新的单元格,其
contentView.frame
的宽度为320(全宽)。以前,当我执行
出列…forindexath
时,它将给出302的宽度,或者单元格的可视/真实宽度。为什么会这样

另外,是否有方法指定重新标记以供重用的UITableViewCells的样式


解决方案:我发现了这个线程,它说当您将autoresizingmask设置为UIViewAutoresizingFlexibleLeftMargin时,当您尝试进行相对定位时,它是固定的(contentView宽度最初是全宽,但当您呈现它时,它会缩小,因此如果您计算正确,它仍然会正确显示)

我在右边放置了一个UISwitch,当我设置自动调整大小的遮罩时,它在第一次显示时工作,但在切换时又移动了20个像素。我不知道是什么导致了额外的移位,但我最终解决了这个问题,只需将UISwitch设置为单元格的accessoryView


(这与最初的问题有部分脱节,但如果有人无意中发现了这一点,也许会有用)。对于特别想知道原始问题的人,答案在第一次编辑下。

因为第一次单元格为零,这就是为什么会调用它的原因:

if (!cell) {
NSLog(@"New cell");
cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}

但是,如果单元格已经准备好重用,并且基本上不是空的,那么当您调用
[tableView registerClass:forCellReuseIdentifier::
时,它返回单元格,并且没有命中上面的if语句,您正在教表视图在以后使用指定的
ReuseIdentifier
时该怎么做。因此,当您稍后调用
[tableView dequeueReusableCellWithIdentifier::
时,它将:

A.获取以前已创建但当前未使用的单元格

B.创建指定类别的新单元格

因此,当您退出队列时,始终会得到一个实例。如果您想使用
initWithStyle:reuseIdentifier:
自己创建新的单元格实例,那么不应该在表视图中注册类。另外,保留注册并添加逻辑来指定需要配置的所有内容(并考虑使用多个不同的单元类和重用标识符)。 当要求为表视图提供新单元格时,从数据源对象调用此方法。如果现有单元格可用,此方法将其出列,或者使用以前注册的类或nib文件创建新单元格。如果没有可重用的单元格,并且您没有注册类或nib文件,则此方法返回nil

出列方法将

  • 返回一个回收的电池(如果有)

  • 如果您注册了一个单元格,请创建一个新单元格(您提到您这样做了)

  • 如果这些都不是真的,则返回nil


  • 我猜如果删除注册(可能隐藏在xib中),那么将得到零结果

    如果您看到UITableView.h

    从iOS 6开始,客户端可以为每个单元注册nib或类

    如果已注册所有重用标识符,请使用较新的-
    dequeueReusableCellWithIdentifier:forIndexPath
    :来确保返回单元实例

    (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
    
    (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_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);
    

    您的单元格是否从情节提要创建到UITableViewController中?所有单元格都是以编程方式创建的。。。是的,很多人说使用故事板。。。但我还不习惯,而且我觉得通过了解实际理解的内容,我会更好地理解它。这没有问题,但我想知道的是,当您从故事板将单元格创建到UITableViewController中时,
    deque
    方法将始终返回有效的单元格(如果使用了正确的标识符)我没有使用intercae生成器。我问题的重点是它永远不会返回零。在“返回回收单元”方面,应用程序首次启动时是否可能有一个回收单元?第一个单元不是回收的,它只是由表视图自动创建的。是的,谢谢,我忽略了带有
    for indexpath:
    的版本与没有的版本之间的区别问题的关键是,第一次它不是零如果我取出
    [tableView registerClass:forCellReuseIdentifier:
    ,我会得到一个“nsInternalConsistencyException: