【问题标题】:Memory Errors with Editable UITableView (iOS 7 ARC)可编辑 UITableView (iOS 7 ARC) 的内存错误
【发布时间】:2014-06-28 13:05:39
【问题描述】:

我在我的应用程序中遇到了错误的内存访问问题,它只发生在特定场景中,我将在此处概述:

1) 在表格单元格上向左滑动,然后使用单元格右侧出现的删除按钮将其删除(一次或多个单元格)。

2) 在做任何其他事情之前(例如向表格中添加另一个单元格),请按导航栏上的后退按钮。

3) 当前视图控制器从导航堆栈中弹出。

4) 加载前一个视图控制器并显示视图。

5) 先前从堆栈中弹出的视图控制器得到它的 dealloc 消息。

6) 此时似乎出现内存访问问题。

我可以使用一些帮助来确定问题的根源。以下是应用崩溃时线程的样子:

Thread

这是错误信息:

Thread 1: EXC_BAD_ACCESS (code=1, address=0xe16d7b52)

它提供的地址有时会有所不同,但除此之外,它始终是相同的信息。我确实知道它发生在上述第 5 步之后,因为我在该视图控制器的 dealloc 方法中放置了一个断点:

- (void)dealloc
{
    // BUGFIX: prevent the tableview from calling delegate methods after
    //   this point.
    photosTableView = nil;    // Problem is at some point after this.

    // [super dealloc]; // Not necessary to explicity call this in ARC
}

您会看到我尝试立即将表设置为 nil,但这并没有改变任何东西,仍然以与以前相同的方式崩溃。请注意,这只发生在我上面概述的场景中。如果您尚未从表格中删除单元格,则按返回不会使应用程序崩溃,也不会在删除单元格后直接向前移动,在删除单元格和按后退按钮之间执行任何操作都会导致应用程序不碰撞。任何有关如何追查此问题原因的建议将不胜感激。

编辑:我认为我的问题可能是我如何实现此方法:

- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If the tableView is asking to commit a delete command...
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Remove the image from the store
        [[SFMImageStore sharedCache] deleteImageAtIndex:[indexPath row]];

        // Reload the table
        [tableView reloadData];
    }
    // EDIT: Adding this forces the tableView out of editing mode
    [tableView setEditing:NO];
}

我尝试注释掉 [tableView reloadData] 只是为了看看会发生什么,并且可以预见的是,该单元格仍然存在于表格中(因为它尚未重新加载)。但令我惊讶的是,删除按钮仍然存在。这就是让我相信,也许我在这里所做的事情可能是罪魁祸首。

编辑:强制表格退出编辑模式会停止打印消息(无论如何我都应该这样做),但是当调用 dealloc 时 tableView 会收到 reloadData 消息仍然很奇怪。

【问题讨论】:

  • 控制器中是否有任何运行的东西被释放?计时器?某种异步操作?
  • 启用僵尸并检查日志是否提及访问已释放对象。
  • 顺便说一句 - 将 photosTableView 设置为 nil 并不能解决任何问题。试试photosTableView.dataSoure = nilphotosTableView.delegate = nil
  • @rdelmar 不,没有计时器或异步操作,或者我能想到的任何其他东西。 @rmaddy “试试 photosTableView.dataSoure = nilphotosTableView.delegate = nil。”这会阻止应用程序崩溃,尽管这会打印到控制台:reloading table view while we're in swipe to delete mode but we don't have a proper swipe to delete index path 我应该关心这个吗?
  • 为什么在释放视图控制器时重新加载表?

标签: ios objective-c uitableview memory-management


【解决方案1】:

在极少数情况下我也遇到过这个问题。在进行 unwind segue 时,有时源视图控制器会在目标视图出现之前被 ARC 释放。它不会发生在我的很多放松转场上,但在它发生的那些上,它每次都会发生。我不知道为什么会这样。我所做的解决方法是在目标“VC 的”展开segue IBAction 方法中设置指向源VC 的指针,我在viewWillAppear 中清除了该指针。它不漂亮,但它有效。

仅供参考,当我检查僵尸工具时,我发现释放是在内部 Apple 过程调用清理源视图控制器之前发生的。过程调用与searchBar 有关(虽然我的 VC 上没有)。

【讨论】:

    【解决方案2】:

    在导航栏中按下返回按钮时,将 tableview.editing 设置为 NO

    //Back Button clicked
    - (void)backButtonClicked{
       [tableView setEditing:NO];
    }
    

    希望这对你有用。

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 1970-01-01
      相关资源
      最近更新 更多