Ios 分配accessoryView时UITableViewCell LayoutSubView上的死锁

Ios 分配accessoryView时UITableViewCell LayoutSubView上的死锁,ios,objective-c,uitableview,cocoa-touch,uikit,Ios,Objective C,Uitableview,Cocoa Touch,Uikit,您好,我在我的应用程序上发现了一个问题,可能不是关键问题,但很奇怪 在我的viewController中有一个开关,我们称之为开关,当我填充单元格时,在indexPath(0,0)上,我将该开关作为附件视图 单元格的标题根据开关的状态而变化 //Code simplified for simplicity if(indexPath.section == 0 && indexPath.row == 0) { cell.textLabel.text = self.filt

您好,我在我的应用程序上发现了一个问题,可能不是关键问题,但很奇怪

在我的viewController中有一个开关,我们称之为开关,当我填充单元格时,在indexPath(0,0)上,我将该开关作为附件视图

单元格的标题根据开关的状态而变化

//Code simplified for simplicity 
if(indexPath.section == 0 && indexPath.row == 0) {
     cell.textLabel.text = self.filtersActivatedSwitch.on ? NSLocalizedString(@"Filters activated", nil) : NSLocalizedString(@"Filters deactivated", nil);
     cell.accessoryView = self.filtersActivatedSwitch;
}
按下开关时,调用此方法

-(void)switchActivated {
     [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:VisibilityFilterTableViewSectionMasterFilter]];
}
这将创建死锁,因为在方法CellForRowatineXpath上,当我尝试将单元格出列时,它将创建一个新的单元格(这是经过测试的,我认为它使用了我想要重新加载的同一个单元格更有意义),并且在单元格的配置中,开关将添加为accessoryView

这就是它变得棘手的地方

BadPirate的回答解释了何时在tableviewcell上调用layoutSubview

-addSubview导致在要添加的视图、要添加到的视图(目标视图)以及目标的所有子视图上调用LayoutSubView

我认为RemoveFromSuperview(假设)也会发生同样的情况,因此新单元格的layoutSubview名为。。它检查accessoryView,查看它是否为nil,以便将其添加到子视图中,另一方面,在旧单元格中(由于任何原因没有退出队列,因此我无法清除accessoryView),LayoutSubview由于removeFromSuperview而被调用(再次假设),它检查accessoryView是否为nil,它将开关添加为子视图。。。永远重复

我的问题是。。。为什么表视图不使用已经出列的单元格?两个TableViewCell具有相同的accessoryView显然会使我的应用程序崩溃

或者我用错了附件视图

干杯

编辑: 这是prepareforeuse上的代码

- (void)prepareForReuse {
  [super prepareForReuse];

  for (UIView *view in self.contentView.subviews) {
      [view removeFromSuperview];
  }

  for (UIView *view in self.imageView.subviews) {
      [view removeFromSuperview];
  }

  self.textLabel.text = nil;
  self.detailTextLabel.text = nil;
  self.imageView.image = nil;
  self.imageView.tag = 0;
  self.accessoryView = nil;
}

单元格是重用的,因此滚动到屏幕外的单元格可以在其他位置重用,并且您添加的任何子视图都仍然存在。在特定的indexPath中添加附件视图时,需要在其中包含一个“else”子句,以告知其他单元格不具有该视图:。我不知道您在CellForRowatineXpath:中还做了什么,但在我的测试方法中,我根本不必使用prepareForReuse方法。我不太明白为什么在switch方法触发时会出现死锁,但是如果在reloadRowsAtIndexPaths:withRowAnimation:method中将动画设置为UITableViewRowAnimationNone,那么一切都正常

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

    if(indexPath.section == 0 && indexPath.row == 0) {
        cell.textLabel.text = self.filtersActivatedSwitch.on ? NSLocalizedString(@"Filters activated", nil) : NSLocalizedString(@"Filters deactivated", nil);
        cell.accessoryView = self.filtersActivatedSwitch;
    }else{
        cell.textLabel.text = self.theData[indexPath.row];
        cell.accessoryView = nil;
    }

    return cell;
}

-(void)switchActivated {

    [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}

cell.accessoryView=UITableViewCellAccessoryNone错误,这是一个枚举,accessoryView需要一个对象。。。您可以传递nil(这是我在if之前所做的。。而且这种情况在没有滚动的情况下发生,即使我只打印1个单元格,那么updaterows死锁就会发生(事实上,我覆盖了prepareforeuse并将所有AccessoryView设置为nil)@沉重的子弹,是的,对不起,我想的是accessoryType,而不是view。你在cellForRow中发布的代码是IndexPath吗?如果你也在实现prepareForReuse,你应该发布该方法以及整个cellForRow方法。你所说的死锁是什么意思?你看到了什么?thx,选中edit,不是很花哨只是设置tableviewcell尽可能的赤裸(在cellforrow上它将被重新填充)@Heavy_子弹,我编辑了我的帖子来展示对我来说有用的东西——主要的是当你重新加载行时没有动画。这!…非常感谢..你帮我省去了很多麻烦..+1并接受了答案