2

我有几个UIViewControllers 添加到内容视图中。调用我的 remove 函数后,我注意到 childUIViewControllerdeinit函数没有被调用,除非我明确地将 child 的值设置UIViewControllernil.

这是正确的行为还是我做错了什么?

func removeViewController(fromCell cell:UICollectionViewCell, at indexPath:IndexPath){
    guard let childViewController = currentViewControllers[indexPath] else { return  }
    print("remove view controller called")
    childViewController.willMove(toParent: nil)
    childViewController.view.removeFromSuperview()
    childViewController.removeFromParent()
    currentViewControllers[indexPath] = nil
    // recycledViewControllers.insert(childViewController)
} 
4

2 回答 2

2

问题是您有两个对子视图控制器的引用:

  • 由父视图控制器自动维护的引用(childViewControllerschildren在现代 Swift 中)

  • 您自己添加的附加参考 ( currentViewControllers)。

因此,您必须在子视图控制器消失之前让它们都消失。这就是您的代码的作用:

childViewController.willMove(toParent: nil)
childViewController.view.removeFromSuperview()
childViewController.removeFromParent()
// now `childViewControllers` / `children` has let go

currentViewControllers[indexPath] = nil
// now `currentViewController` has let go

因此,您本身并没有做错任何事情,除非您currentViewControllers首先通过添加这个额外的强参考。但我明白你为什么这样做:你想要一种将索引路径与子视图控制器配对的方法。

因此,您可以很好地使用您的方法,或者如果您真的想要,您可以currentViewControllers只对它的值进行引用(通过使用NSMapTable而不是字典)。

于 2019-04-29T16:59:11.987 回答
-1

苹果的文档说:

Swift 通过自动引用计数 (ARC) 处理实例的内存管理...

就在实例释放之前,会自动调用反初始化器。您不能自己调用​​反初始化器。

这基本上意味着您deinit()不能自己调用​​该方法,并且除非strong对它们的引用为零,否则不会取消初始化。

于 2019-04-29T16:49:53.030 回答