Пользовательская функция делегата не вызывается до UIAlertController Подкласс Увольнение - PullRequest
0 голосов
/ 31 марта 2020

Я создал подкласс UIAlertController, который делает что-то, но перед тем, как отменить его, я называю Delegate (это собственный протокол для шаблона делегирования, чтобы использовать его в UIViewController), прямо перед оператором dimiss

  • Вставил этот код в моем классе пользовательских оповещений.
  • У меня есть сильная ссылка на него в UIViewController, и я установил для делегата значение self.
  • Соответствующий протокол и установка точки останова, никогда не достигнутой во время выполнения.
// this code in my custom subClass of UIAlertController 

   func addRequestAction() {
        addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak self] _ in
            self?.checkConnection { isConnected in
                print("xxxxxxxxx", isConnected)
                DispatchQueue.main.async {
                    if isConnected {
                        self?.delegate?.didConnect() // here i call delegate function but never executed
                        self?.dismiss(animated: true, completion: nil)
                    } else {
                        let alert = NetworkCheckerAlert(self?.delegate)
                        self?.dismiss(animated: true, completion:nil)
                        guard let viewController = UIApplication.shared.keyWindow?.rootViewController else { return }
                        viewController.present(alert, animated: true, completion: nil)
                    }
                }
            }
        }))
    }

1 Ответ

1 голос
/ 31 марта 2020

Удаление [weak self] должно решить проблему:

addAction(UIAlertAction(title: "OK", style: .default, handler: { /*[weak self]*/ _ in

Обычно в контроллере представления использовать [weak self] нормально, поскольку self относится к V C, но здесь self относится к UIAlertController.

Я предполагаю, что вы не сохраняете ссылку на свой настраиваемый контроллер оповещений, когда вы его представляете (т.е. вы просто объявляете его как локальную переменную, представляете его и бросаете это прочь).

Теперь давайте рассмотрим, что происходит при запуске замыкания DispatchQueue. К этому моменту предупреждение уже было отклонено, поэтому «экран» не сохраняет ссылку на него. Поскольку ничто не сохраняет сильную ссылку на контроллер предупреждений (существует только слабая ссылка из замыкания), экземпляр подкласса UIAlertController освобожден.

Это всего лишь предположение. Вы можете сделать больше исследований, увидев, какие объекты находятся в памяти, и кто хранит ссылку на кого, используя описанный метод здесь (написанный мной).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...