如何取消初始化子UIViewController?

问题描述 投票:2回答:2

我有几个UIViewControllers添加到内容视图。调用我的删除函数后,我注意到除非我明确地将子UIViewController的值设置为deinit,否则不会调用子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)
} 
ios swift uiviewcontroller automatic-ref-counting deinit
2个回答
2
投票

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

  • 父视图控制器自动维护引用(childViewControllers,或现代Swift中的children
  • 您自己添加的另一个参考(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而不是字典)。


-1
投票

Apple's Documentation说:

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

在实例解除分配之前,会自动调用取消初始化程序。您不能自己致电deinitializer。

这基本上意味着你不能自己调用​​deinit()方法,除非strong没有引用它们,否则事情不会被取消初始化。

© www.soinside.com 2019 - 2024. All rights reserved.