【问题标题】:Table View Reload Sections Crashes表视图重新加载部分崩溃
【发布时间】:2015-01-01 16:45:23
【问题描述】:

我有一个包含 4 个部分的表格视图,每个部分有 1-2 个表格视图单元格。第一个单元格有一个 uiswitch 作为附件视图并控制应用程序的颜色主题,在白天模式和夜间模式之间切换。一旦按下开关,就会调用一个函数,更改导航栏的颜色和背景颜色。在那个函数中,我还写了一行

[self.tableview reloadData];

用新颜色更新表格本身。它工作正常,但没有动画,所以我用这个代替

[self.tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)] withRowAnimation:UITableViewRowAnimationFade];

使用该行时,开关会卡住,应用程序会冻结。它不会崩溃,即没有崩溃日志,它只是冻结并且 uiswitch 停止中间动画。

我注意到我可以重新加载没有包含附件视图的单元格的部分,并且它与淡入淡出动画完美配合。 IE。这行得通

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];

因为第三部分没有任何带有辅助视图的单元格。但是,如果我尝试重新加载任何具有包含附件视图的单元格的部分(即第 0 和 2 部分),应用程序将冻结。

任何想法为什么会发生这种情况?下面是我的 cellForRowAtIndexPath

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

static NSString *cellIdentifier;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];

if (indexPath.section == 0) {

    cell.textLabel.text = [section0 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (indexPath.row == 0) {

        cell.accessoryView = colorSchemeSwitch;
    }

    else if (indexPath.row == 1) {

        cell.accessoryView = autoLockSwitch;
    }
}

else if (indexPath.section == 1) {

    cell.textLabel.text = [section1 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

else if (indexPath.section == 2) {

    cell.textLabel.text = [section2 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%i \t", (int)app.fontSize];
    fontSizeSlider.value = app.fontSize;
    cell.accessoryView = fontSizeSlider;
}

else if (indexPath.section == 3) {

    cell.textLabel.text = [section3 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.detailTextLabel.text = app.color;
}

cell.backgroundColor = app.cellBackgroundColor;
cell.textLabel.textColor = app.textColor;
UIView *backgroundColorView = [[UIView alloc] init];
backgroundColorView.backgroundColor = app.cellSelectedColor;
[cell setSelectedBackgroundView:backgroundColorView];

return cell;
}

【问题讨论】:

  • 请在您的问题中附加崩溃日志。
  • 这真的很奇怪,没有崩溃日志,应用程序冻结,它没有崩溃。开关卡在中间,应用程序变得无响应。没有崩溃日志
  • 您可以管理表格单元格的对象。并避免在 CellForRawAtIndexPath: 方法中进行大量计算。尽量保持简单。

标签: ios objective-c uitableview reload sections


【解决方案1】:

您尚未添加崩溃日志,但我猜您收到一个错误,指出一个部分中的现有行数必须等于更新前的某个值。如果是这样的话, 重载表格前使用[self.tableview beginUpdates],重载后使用[self.tableview endUpdates]

【讨论】:

  • 奇怪的是,没有崩溃日志,应用卡死了,没有崩溃
  • 我尝试将代码与开始和结束更新夹在中间,但没有任何变化
  • 尝试在这里添加 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ //把代码放在这里});
  • 试过了,代码没有执行,应用仍然死机。再次没有可用的崩溃日志
  • 好的,通过将 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^ 改为 dispatch_get_main_queue(), 将其添加到主线程
【解决方案2】:

我在UITableViewCell 中遇到了同样的问题,包括UISwitch。在重新加载部分之前,我通过调用[self.tableview reloadData] 解决了这个问题:

NSIndexSet *sections = [[NSIndexSet alloc] initWithIndex:2];
[self.tableView reloadData];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];

如果你打电话也会出现同样的问题:

[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationFade]

无需先重新加载数据。

【讨论】:

  • 你是个传奇!那工作得很好。不敢相信就这么简单
  • 如果我们调用重新加载表,那么为什么动画需要重新加载部分? (H)
  • 我同意@dip,应该调用“reloadData”或“reloadSections”,但不能同时调用。话虽如此,我在“beingUpdates”和“endUpdates”之间仅使用“reloadSections”随机得到一个 SIGABRT 崩溃。我仍在试图找出原因......
  • 我同意上述cmets。要么用reloadData,要么用reloadSections,都没有意义
  • 我相信您需要至少调用一次 reloadData - 以便调用 numberOfSections 委托函数。然后,您可以根据需要调用 reloadSection(在您的部分数量不变的情况下)。
【解决方案3】:

我在尝试重新加载特定行时遇到了同样的问题。我的数据源不一致。因为我正在从远程加载数据。我发现这个link 解决了这个问题。 但我需要修改这一行。

let sections = dataSource.numberOfSections?(in: self) ?? 0

let sections = dataSource.numberOfSections?(in: self) ?? 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多