Удаление всех ранее загруженных ViewControllers из памяти iOS Swift

#ios #swift #uiviewcontroller #presentviewcontroller

#iOS #быстрый #uiviewcontroller #presentviewcontroller #swift

Вопрос:

В настоящее время я редактирую ранее написанный код В приложении, первый ViewController — это контроллер представления таблицы с именем: ListViewController, который имеет несколько элементов, каждый выбор строки создает новый экземпляр контроллера представления и представляет его модально. но в этих контроллерах просмотра вместо их удаления предыдущий разработчик снова создал экземпляр ListViewController и модально представляет его для возврата.

Приложение, очевидно, использует много памяти.

Отклонение контроллеров просмотра не является вариантом.

если я помещаю контроллеры просмотра в стек один за другим, это не работает, В каждом представлении есть всплывающие окна и т. Д., Представленные в viewDidAppear.

Мне нужно удалить все ранее загруженные ViewControllers из памяти и представить ViewController таким образом, чтобы в памяти не осталось экземпляров каких-либо ViewControllers. Возможно ли это? Есть ли способ, которым я могу сказать, что новый ViewController с именем HomeViewController гарантирует, что все ранее загруженные экземпляры всех контроллеров просмотра будут выпущены.

Сценарий выглядит следующим образом:

                          ListViewController 
                     /            |             
             AViewController  BViewController  CViewController
  

ListViewController имеет 3 элемента

A B C

пользователь может нажать на любой из них, что приводит к представлению ViewController. и из каждого из контроллеров просмотра при нажатии кнопки «Назад» отображается ListViewController.

Представления представляются с использованием следующего кода:

 if let listViewController = storyboard!.instantiateViewControllerWithIdentifier("ListViewController") as? ListViewController {
                    self.presentViewController(listViewController, animated: true, completion: nil)
                }
  

Комментарии:

1. разве вы не можете сохранить логическое значение, которое будет отмечать, отображалось ли всплывающее окно или нет в viewDidAppear? затем вы можете всплывать, и всплывающие окна не будут запускаться. но похоже, что все это нужно переработать

2. Почему вы не можете отклонить VCs?

3. Я согласен, каждый контроллер представления использует разные ресурсы, между ними есть даже игровая сцена SpriteKit. Невозможно ли перейти к новому контроллеру представления, выпустив все предыдущие, например, приложение только что запущено, никаких свойств или состояний не требуется, просто новый старт.

4. @Sweeper когда я отклоняю VC, отображается предыдущий, я имею в виду, если ListViewController представлял их, то отклонение было очень простым, но каждый контроллер представления либо представляет ListViewController, либо любой другой контроллер представления. Таким образом, это может быть любая возможная комбинация, например, ListViewController -> A -> ListViewController -> B -> C -> A -> ListViewController -> A

5. @Hammadzafar Похоже, что реализация кнопки «Назад» плохая. Вы должны просто изменить кнопку «Назад», чтобы она закрывала / открывала VCs

Ответ №1:

Я не уверен, что это сработает. Попробуйте это. Перед представлением любого нового ViewController .

Создайте метод в AppDelegate

 func switchControllers(viewControllerToBeDismissed:UIViewController,controllerToBePresented:UIViewController) {
        if (viewControllerToBeDismissed.isViewLoaded amp;amp; (viewControllerToBeDismissed.view.window != nil)) {
            // viewControllerToBeDismissed is visible
            //First dismiss and then load your new presented controller
            viewControllerToBeDismissed.dismiss(animated: false, completion: {
                self.window?.rootViewController?.present(controllerToBePresented, animated: true, completion: nil)
            })
        } else {
        }
    }
  

Теперь предположим, что вы перемещаетесь следующим образом

ViewController —> Вы нажимаете кнопку и представляете SecondViewController

Итак, в настоящее время у нас есть ViewController и SecondViewController в памяти.

Теперь, когда вы нажимаете какую-либо кнопку SecondViewController , чтобы представить a ThirdViewController , затем SecondViewController должны отклонить. Итак SecondViewController , нажмите кнопку

 @IBAction func buttonPress(_ sender: AnyObject) {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    let controllerToBePresented = self.storyboard?.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
    appDelegate.switchControllers(viewControllerToBeDismissed: self, controllerToBePresented: controllerToBePresented)
}
  

Итак, теперь у нас есть ViewController и ThirdViewController в памяти.
SecondViewController удаляется из памяти.

Лучшее решение — сохранить ваши контроллеры в UINavigationController стеке, потому что вы можете получить массив всех ViewControllers отправленных в стек.

Комментарии:

1. Спасибо, я пробовал, но это не работает. Когда я использую этот код, if всегда принимает значение true, и он не отключает текущий контроллер представления и не представляет новый.

2. вы должны написать код для увольнения.. Я только что сделал в комментариях.. First dismiss and then load your new presented controller

3. Да, это то, что я делаю, вот код: if oldVC.isViewLoaded() amp;amp; oldVC.view.window != nil { oldVC.dismiss if let AVC = storyboard!.instantiateViewControllerWithIdentifier("A") as? AViewController { presentVC(AVC) } } else { if let AVC = storyboard!.instantiateViewControllerWithIdentifier("A") as? AViewController { presentVC(AVC) } } }

4. где вы пишете этот код? Это должно быть где-то, где класс должен существовать в памяти, например, AppDelegate. Подождите, я отредактирую

5. Я внедрил ваше решение, оно работает в нескольких виртуальных машинах, так что это означает, что ваше решение правильное, быстрый вопрос, отклоняет ли ViewController, как мы, освобождает ли это память, которую он использовал? потому что я отслеживаю используемую память и не вижу никаких изменений по сравнению с предыдущим использованием.