【问题标题】:How to properly use "dequeueReusableCellWithIdentifier:" with multiple identifiers?如何正确使用具有多个标识符的“dequeueReusableCellWithIdentifier:”?
【发布时间】:2011-12-23 22:17:24
【问题描述】:

我有一个 Core Data 支持的表格视图,它显示可编辑字段的列表,对于不同的字段类型,我有不同的 UTableViewCells 和不同的单元格标识符。当我在模拟器中滚动得太快或试图“弹跳”过去最后一个单元格时,我会崩溃,说 UITableView dataSource 必须从 tableView:cellForRowAtIndexPath 返回一个单元格。如果我删除 dequeueReusableCellWithIdentifier: 步骤,整个问题就会消失。这意味着我的表格视图效率较低。我在表格视图中最多使用 20 个获取的对象(更多的是 8-10 个),因此效率低下可能是一个小问题。我只是想知道我是否做错了什么。

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

    Field *aField = [self.fetchedResultsController objectAtIndexPath:indexPath];
    static NSString *CellIdentifier = @"Cell";
    static NSString *ChoiceIdentifier = @"ChoiceCell";
    static NSString *SwitchIdentifier = @"SwitchCell";

    UITableViewCell *cell;

    if ([aField.fieldType isEqualToString:@"choice"] || [aField.fieldType isEqualToString:@"date"]  || [aField.fieldType isEqualToString:@"multiChoice"] ) {

        NSLog(@"ChoiceCell");
        cell = [tableView dequeueReusableCellWithIdentifier:ChoiceIdentifier];
        if (cell == nil) {
            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                [[NSBundle mainBundle] loadNibNamed:@"ChoiceTableViewCell-iPad" owner:self options:nil];
            } else {
                [[NSBundle mainBundle] loadNibNamed:@"ChoiceTableViewCell" owner:self options:nil];
            }
        }

    } else if ([aField.fieldType isEqualToString:@"boolean"]){

        NSLog(@"SwitchCell");
        cell = [tableView dequeueReusableCellWithIdentifier:SwitchIdentifier];
        if (cell == nil) {

            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                [[NSBundle mainBundle] loadNibNamed:@"SwitchTableViewCell-iPad" owner:self options:nil];
            } else {

                [[NSBundle mainBundle] loadNibNamed:@"SwitchTableViewCell" owner:self options:nil];
            }
        }


    } else {

        NSLog(@"Cell");
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                [[NSBundle mainBundle] loadNibNamed:@"EditableTableViewCell-iPad" owner:self options:nil];
            } else {

                [[NSBundle mainBundle] loadNibNamed:@"EditableTableViewCell" owner:self options:nil];
            }
        }
    } 

    cell = editableCell;
    self.editableCell = nil;


    // Configure the cell...
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

其他详细信息: editableCell 设置为与自定义单元格对应的每个 NIB 中。我尝试通过说更直接地设置它

dynamicCell = [[[NSBundle mainBundle] loadNibNamed:@"ChoiceTableViewCell-iPad" owner:self options:nil] objectAtIndex:0];

但仍然有同样的问题。它永远不应该返回零。只要我不滚动太快,所有的 NIB 都会被加载。我已经两次和三次检查了 NIB 名称以确保。

这是更新后的工作代码:

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

{

Field *aField = [self.fetchedResultsController objectAtIndexPath:indexPath];
static NSString *CellIdentifier = @"Cell";
static NSString *ChoiceIdentifier = @"ChoiceCell";
static NSString *SwitchIdentifier = @"SwitchCell";


if ([aField.fieldType isEqualToString:@"choice"] || [aField.fieldType isEqualToString:@"date"]  || [aField.fieldType isEqualToString:@"multiChoice"] ) {

    NSLog(@"ChoiceCell");
    dynamicCell = [tableView dequeueReusableCellWithIdentifier:ChoiceIdentifier];
    if (dynamicCell == nil) {
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {


            [[NSBundle mainBundle] loadNibNamed:@"ChoiceTableViewCell-iPad" owner:self options:nil];
        } else {
            [[NSBundle mainBundle] loadNibNamed:@"ChoiceTableViewCell" owner:self options:nil];
        }
    }

} else if ([aField.fieldType isEqualToString:@"boolean"]){

    NSLog(@"SwitchCell");
    dynamicCell = [tableView dequeueReusableCellWithIdentifier:SwitchIdentifier];
    if (dynamicCell == nil) {

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            [[NSBundle mainBundle] loadNibNamed:@"SwitchTableViewCell-iPad" owner:self options:nil];
        } else {

            [[NSBundle mainBundle] loadNibNamed:@"SwitchTableViewCell" owner:self options:nil];
        }
    }


} else {

    NSLog(@"Cell");
    dynamicCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (dynamicCell == nil) {
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            [[NSBundle mainBundle] loadNibNamed:@"EditableTableViewCell-iPad" owner:self options:nil];
        } else {

            [[NSBundle mainBundle] loadNibNamed:@"EditableTableViewCell" owner:self options:nil];
        }
    }
} 

UITableViewCell *cell;
cell = dynamicCell;
self.dynamicCell = nil;


// Configure the cell...
[self configureCell:cell atIndexPath:indexPath];
return cell;

}

【问题讨论】:

  • 您的重用标识符是否在笔尖中正确设置?你不应该为 iPad 设置一个特殊的 if 分支。 NSBundle 可以自己加载正确的 nib。为了简化代码,您还应该只调用一次 [bundle loadNib:filename] 并仅使用 if-branches 来设置变量“NSString* 文件名”。

标签: ios core-data uitableview


【解决方案1】:

看起来问题出在:

cell = editableCell

如果 editableCell 为 nil,您的应用将崩溃。我假设您打算将editableCell 设置为loadNibNamed:。如果您将单元格出列,则不会设置它。

【讨论】:

  • 我会试一试,但如果是这种情况,它如何在第一次尝试加载时不崩溃?
  • b/c 您没有在第一次加载时将单元格出列(即没有任何内容可出列,因此所有单元格都是从 nib 文件创建的)。
  • 谢谢,您的回复本可以更详细一点,但它让我到达了我需要的地方。
  • 呵呵,是的,我想。我更喜欢“教人钓鱼……”的方法。很高兴你解决了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2016-04-04
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
相关资源
最近更新 更多