Как я могу управлять и освободить память через ViewControllers
У меня большие проблемы, и единственная причина, по которой я не могу найти решение, заключается в том, что у меня недостаточно знаний о swift и управлении памятью в swift. Так что вот мои проблемы. Я работаю в Swift 4.0 и iOS 9.3
Я на самом деле делаю приложение для галереи изображений с помощью входа / выхода. Основное применение. Я работаю в cleanSwift Так что у меня нет этих огромных ViewControllers.
Мое приложение отдельно в 3 ВК: логин, галерея и настройки (которые содержат LogOut).
Здесь моя проблема. Когда я выхожу из системы, я хочу создать новый loginVC и очистить все предыдущие VC. Так что у меня есть функция cleanMemory, которая устанавливает все UIImage на ноль
func cleanMemory(request: Gallery.Request) { // Interactor
worker.cleanMemory(completionHandler: { (Value) in
self.interventions?.removeAll() // Interventions contains UIImages
self.interventionsSelected.removeAll() // InterventionsSelected contains UIImages
})
}
а затем я удаляю остатки UIImage и VC
func cleanMemory() {
interactor?.cleanMemory(request: Gallery.Request())
self.displayedInterventions.removeAll() // displayedInterventions contains UIImages
interactor = nil
router = nil
self.removeFromParentViewController()
self.navigationController?.popViewController(animated: true)
}
Но когда я создаю свой новый LoginVC.. моя RAM не уменьшается.. И когда я проверяю память приложения, ни один VC не был удален.. И когда я выполняю цикл Logout/Login 3 раза, мое приложение падает, потому что я не очень хорошо управляю своей RAM_
Так где я ошибся и почему??
Спасибо за ваш ответ.
РЕДАКТИРОВАТЬ: у меня было 2 проблемы:
- Мое завершениеХандлер поддерживал мой ВК
- Я переключал ВК с.present, так что я держал свой ВК в памяти.
Таким образом, вы должны изменить VC следующим образом:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationVC = storyboard.instantiateViewController(withIdentifier: "LoginController")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = destinationVC
1 ответ
Удалять viewController
из памяти вам просто нужно удалить его из стека навигации. Поэтому, когда вы звоните navigationController?.popViewController(animated: true)
и возвращаясь к предыдущему контроллеру представления, вы уже уничтожаете этот контроллер.
Затем,
Здесь моя проблема. Когда я выхожу из системы, я хочу создать новый loginVC и очистить все предыдущие VC. Так что у меня есть функция cleanMemory, которая устанавливает все UIImage на ноль
при выходе из системы рекомендуется остановить все запросы, но вам не нужно вносить какие-либо изменения в пользовательский интерфейс, поскольку это занимает некоторое время и не требует "удаления контроллера из памяти". Как проверить, полностью ли удален контроллер вида из стека навигации? Просто пиши print
заявление в deinit
func, скомпилируйте код и вернитесь из этого контроллера представления.
deinit {
print("ViewController deinit")
}
Если это print
работает нормально (вы можете увидеть текст в консоли xcode), вы достигнете результата - контроллер был удален из стека навигации, но если нет print
В результате вы, вероятно, забудете правильно управлять своими замыканиями. Например
worker.cleanMemory(completionHandler: { (Value) in
...
})
это закрытие может удерживать ваш контроллер, когда вы думаете, что контроллер уже освобожден, и это означает, что ваш контроллер присутствует где-то в памяти. Чтобы предотвратить это retain cycles
вам нужно использовать [unowned self]
из [weak self]
(просто Google по этим ключевым словам, это очень легко понять), как это:
// or you can use `[unowned self]`
worker.cleanMemory(completionHandler: { [weak self] (Value) in
guard let `self` = self else { return } // only for `weak` way
...
})
Таким образом, в этом случае нет ничего, что может удержать ваш контроллер после pop from navigation stack
действие или около того. Это простые правила, которым вы должны следовать, чтобы написать хорошо управляемый код.