Как деинициализировать дочерний UIViewController? - PullRequest
2 голосов
/ 29 апреля 2019

У меня есть несколько UIViewController s, которые добавляются к представлению содержимого.После вызова моей функции удаления я замечаю, что дочерняя функция 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)
} 

Ответы [ 2 ]

2 голосов
/ 29 апреля 2019

Проблема в том, что у вас есть две ссылки на контроллер дочернего представления:

  • Ссылка поддерживается автоматически родительским контроллером представления (childViewControllers или children в современном 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 словаря).

0 голосов
/ 29 апреля 2019

Документация Apple гласит:

Swift управляет памятью экземпляров посредством автоматического подсчета ссылок (ARC) ...

и

Деинициализаторы вызываются автоматически, непосредственно перед освобождением экземпляра.Вы не можете вызывать деинициализатор самостоятельно.

Это в основном означает, что вы не можете вызывать метод deinit() самостоятельно и что вещи не будут деинициализированы, если нет нулевых ссылок strong.им.

...