代码之家  ›  专栏  ›  技术社区  ›  kolinko

滚动TableView时EXC_BAD_ACCESS

  •  0
  • kolinko  · 技术社区  · 16 年前

    在我的程序中,我正在创建从nib文件加载的两个自定义uiviewcell:

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

    加载后,我设置它们并从函数返回:

    if (indexpath.row == 1) {
        [nibTextInputer setupWithName:@"notes" ...];
        return nibTextInputer;
    } else {
        [nibSelectInputer setupWithName:@"your_choice" ...];
        return nibSelectInputer;
    };
    

    其中nibTextInputer属于我的类(aftexputer),nibSelectInputer属于我的另一类(aftexputer)。两个类都是UITableViewCell的子类。

    一切都很好,但当我添加缓存时会中断:

    Boolean inCache = false;
    if (indexPath.row == 1) {
       UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"nibTextInputer"];
       if (cell != nil) {
          NSLog(@"%@", [cell description]); // prints out ok, correct type.
          nibTextInputer = (AFTextInputer*) cell;
          inCache = true;
       };
    };
    
    if (!inCache) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomCells" owner:self options:nil];
    }
    

    一旦我添加了上述EXC_BAD_ACCESS,它就会随机出现,通常没有附加信息,有时还会出现以下错误:

    -[CALayer prepareForReuse]: unrecognized selector sent to instance
    

    甚至

    -[UIImage prepareForReuse]: unrecognized selector sent to instance
    

    EXC_BAD_ACCESS的位置似乎是随机的。有时在“出列”之后,有时在函数之外。。

    我想问题出在我的自定义uiviewcell实现中,但我不知道从哪里开始查找。。

    思想?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Cory Kilger    16 年前

    您的 UITableViewCell . -[UITableViewCell prepareForReuse] 在返回之前被调用 -[UITableView dequeueReusableCellWithIdentifier:] ,但当它被调用时,该单元不再存在,而是一个CALayer、UIImage或其他您无法访问的内容。

    问题可能在于加载自定义单元格的方式。值得一提的是,我通常是这样做的:

    static NSString *CellIdentifier = @"CustomCell"; // This string should also be set in IB
    
    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = nibCell; // nibCell is a retained IBOutlet which is wired to the cell in IB
    }
    
    // Set up the cell...
    
        2
  •  0
  •   Shaggy Frog    16 年前

    这可能是你遇到问题的地方:

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

    UITableView类将所有单元格聚合到同一个池中以供重用;它不知道某些单元格是一种子类(即aftexputer),而某些单元格是另一种子类(即aftexputer)。所以当你在 if (indexPath.row == 1) block,你可能得到了错误的子类单元格。“identifier”只是一个字符串,它向内置缓存指示正在引用哪个表的单元格;它实际上并不使用该字符串深入缓存以查找具有匹配子类名称的对象。

    P、 为什么你要用一种叫做 Boolean 而不是“内置” BOOL ?