如何取消初始化子 UIViewController?
How do I deinitialize a child UIViewController?
我有几个 UIViewController
添加到内容视图中。调用我的删除函数后,我注意到子 UIViewController
的 deinit
函数没有被调用,除非我明确地将子 UIViewController
的值设置为 nil
.
这是正确的行为还是我做错了什么?
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)
}
Swift handles the memory management of instances through automatic reference counting (ARC)...
和
Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself.
这基本上意味着您不能自己调用 deinit()
方法,除非对它们的 strong
引用为零,否则不会取消初始化。
问题是您有 两个 对子视图控制器的引用:
父视图控制器自动维护的引用(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
设置为只有 weak 引用它的值(通过使用NSMapTable 而不是字典)。
我有几个 UIViewController
添加到内容视图中。调用我的删除函数后,我注意到子 UIViewController
的 deinit
函数没有被调用,除非我明确地将子 UIViewController
的值设置为 nil
.
这是正确的行为还是我做错了什么?
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)
}
Swift handles the memory management of instances through automatic reference counting (ARC)...
和
Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself.
这基本上意味着您不能自己调用 deinit()
方法,除非对它们的 strong
引用为零,否则不会取消初始化。
问题是您有 两个 对子视图控制器的引用:
父视图控制器自动维护的引用(
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
设置为只有 weak 引用它的值(通过使用NSMapTable 而不是字典)。