【问题标题】:How to prevent UIViewController from re-instantiating during segues?如何防止 UIViewController 在 segues 期间重新实例化?
【发布时间】:2017-07-15 18:00:24
【问题描述】:

我在 UIViewController 中有一个 UITableView(让我们调用该视图控制器 B),我一次填充一个对象。对象在之前的 UIViewController(视图控制器 A)中创建,并在视图控制器 A 的 prepare(for segue:_) 函数中添加到表的数据源(也是视图控制器 B)中。这会将一个对象添加到表格,此时用户可以点击“添加到表格”单元格,将他们带回控制器 A,然后重复该过程。问题是每次我返回视图控制器 B 时,表视图只有最近添加的对象。我相信这是因为每个 segue 都在创建它要移动到的 ViewController 的新实例。如何防止这种情况发生,或者找到一个更好的位置来存储不会每次都被重新实例化和覆盖为空列表的 tableview 数据源?

查看控制器 A

class ViewControllerA : UIViewController {

    var object = MyObject(...)

    ...

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let viewB = segue.destination as! ViewControllerB


        viewB.dataSource.append(object) //


    }
}

视图控制器 B

class ViewControllerB: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var dataSource = [MyObject]()

    //DataSource functions fill table with dataSource array objects
    ...
}

【问题讨论】:

    标签: swift uitableview uiviewcontroller


    【解决方案1】:

    您丢失数据的原因是因为每次尝试执行 segue 时都会重新创建视图控制器 B。因此,要保留数据,您必须将数据从视图控制器 B 传递回视图控制器 A。然后,当您单击视图控制器 A 上的其他内容时,您需要将新数据附加到现有数据,然后传递给控制器​​ B再次。

    要传回数据,您需要查看 unwind segue。 Here 是一个很好的实现示例。

    【讨论】:

    • 啊,所以我想确实没有有效的方法来阻止 ViewController 本身恢复。感谢您链接到 unwind 实现,我还不知道如何使用它们。
    【解决方案2】:

    当您点击“添加到表格”按钮时,您可以将整个数组传回给 ViewController A。然后,将新对象附加到整个列表中,并将其分配给 ViewController B 中的变量

    答:

    class ViewControllerA : UIViewController {
    
        var dataSource = [MyObject]()  // Now you have a dataSource variable in both viewControllers
        var object = MyObject()
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
            let viewB = segue.destination as! ViewControllerB
    
            dataSource.append(object)  // Add the new object
            viewB.dataSource = dataSource  // Assign the newly-updated array
        }
    }
    

    乙:

    class ViewControllerB: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
        var dataSource = [MyObject]()
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
            let viewA = segue.destination as! ViewControllerA
    
            viewA.dataSource = dataSource
        }
    }
    

    【讨论】:

      【解决方案3】:

      这是正确的,因为每次从ViewControllerB 切换回ViewControllerA 时,ViewControllerB 都会从内存中释放,连同它的数据源。当您在prepareForSegue 中实例化ViewControllerB 时,我建议您从ViewControllerA 传递一个dataSource 数组。像这样的...

      class ViewControllerA : UIViewController {
          var selectedItems: MyObject = []
          var object = MyObject(...)
      
      ...
      
      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
          let viewB = segue.destination as! ViewControllerB
      
          viewB.dataSource = selectedItems
      }
      

      这样,ViewControllerA 即使在 ViewControllerB 被解除分配后也会跟踪所有选定的项目。

      【讨论】:

        猜你喜欢
        • 2014-08-16
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 2013-10-14
        • 2012-01-11
        相关资源
        最近更新 更多