Делегат протокола иногда не работает

У меня проблема с делегатом протокола, который не всегда отвечает. Вот моя реализация:

protocol CameraViewDelegate: class {
    func didTapCancel(sender: CameraView)
    func didFinishSelectingPhoto(image: UIImage, sender: CameraView)
}

В классе CameraView у меня есть:

weak var delegate: CameraViewDelegate?

а также

@IBAction func cancelButtonTapped() {
    delegate?.didTapCancel(self)
}

@IBAction func sendPhotoTapped() {
    if let image = selectedImage {
        delegate?.didFinishSelectingPhoto(image, sender: self)
    }
}

В другом классе у меня есть:

class PhotoController: CameraViewDelegate {

а также

func didTapCancel(sender: CameraView) {
    dismissViewControllerAnimated(true, completion: nil)
    RootViewController.shared().navigateToHome()
}

func didFinishSelectingPhoto(image: UIImage, sender: CameraView) {
    let photo = MyPhoto(image: image)
    sendPhoto(photo)
    dismissViewControllerAnimated(true, completion: nil)
}

Это работает в 95% случаев, но я получаю странную ошибку, когда делегат иногда не отвечает. Если я нажму кнопку «Отмена» или «Отправить фото», кнопка нажимается, но ничего не происходит. Я знаю, что делегат не отвечает, потому что другие кнопки в CameraView, которые не используют делегата, все еще работают нормально.

Любые идеи?


person charliework    schedule 05.04.2017    source источник
comment
как вы установили свойство delegate вашего класса CameraView в другом классе?   -  person nayem    schedule 05.04.2017
comment
Бывает ли такое, когда делаешь все очень быстро? См. здесь. Ответ Пауло, вероятно, опасен, он приведет к утечке памяти.   -  person Honey    schedule 05.04.2017
comment
@Honey Это был просто быстрый и грязный совет по отладке, ха-ха! Во всяком случае, улучшенный ответ, чтобы держать OP на правильном пути. Спасибо за ответ!   -  person Paulo Mattos    schedule 05.04.2017
comment
@Honey, кажется, это постоянно происходит при первом запуске новой установки. Если я выйду из приложения и снова открою, оно будет работать как положено.   -  person charliework    schedule 05.04.2017
comment
Я просто плюю: очень вероятно, что-то nil где-то и пока вы запускаете/отправляете сообщение на него функции. Скорее всего, вы не узнаете, где именно, потому что вы безопасно разворачиваете. Например, где-то в приведенном выше связанном ответе вы выпускаете self раньше или выпускаете объект раньше. Может помочь попытка принудительно развернуть, чтобы вы разбились на объекте nil и точно определили его. Как только вы его нашли, отредактируйте свой вопрос с возможным нулевым объектом.   -  person Honey    schedule 06.04.2017


Ответы (3)


Совет по отладке. Попробуйте временно удалить квалификатор weak из свойства delegate. Возможно, вы слишком рано освобождаете свой объект делегата (т. е. ноль четкие ссылки на него).

Если это решит вашу проблему, то вы нашли свою ошибку, поздравляю! Пожалуйста, вставьте еще раз квалификатор weak, чтобы избежать излишней утечки памяти — и не забудьте сохранить сильную ссылку на него в другом месте :-)

person Paulo Mattos    schedule 05.04.2017
comment
Вы должны привести пример с как сохранить сильную ссылку на него в другом месте. - person nayem; 05.04.2017

Я думаю, вам нужно назначить другой делегат контроллера вида = self, откуда вы нажимаете камеру

person Arvind Patel    schedule 05.04.2017

Проверьте, установили ли вы delegate при инициализации вида камеры. Попробуйте что-то вроде:

let cameraView = CameraView() 
cameraView.delegate = self
person Ender    schedule 05.04.2017