Делегирование другому контроллеру представления не работает - PullRequest
0 голосов
/ 08 сентября 2018

Мой класс отправителя для делегирования:

import UIKit

protocol tapDelgation:class {
    func tapConfirmed(message:String)
}

class ViewController: UIViewController {
    weak var delegate:tapDelgation?

    @IBAction func deligateSenderAction(_ sender: Any) {
        var data = "hello world"
        print(data)
        self.delegate?.tapConfirmed(message: data)
    }
}

Мой класс приемника:

import UIKit

class NextViewController: UIViewController {
    weak var vc:ViewController? =  ViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        vc?.delegate = self
    }
}

extension  NextViewController : tapDelgation {
    func tapConfirmed(message: String) {
        print(message)
    }
}

Что ожидается: нажата кнопка на отправителе vc, и из приемника vc будет выведена консольная печать. Но зря ничего не происходит. Кто-нибудь знает, почему это происходит? Если это невозможно, то почему?

Ответы [ 3 ]

0 голосов
/ 09 сентября 2018
weak var vc:ViewController? =  ViewController()

Удалите слабый, если вы не устанавливаете vc где-то еще, и любой другой экземпляр не сохраняет сильную ссылку на него.

Если есть другой экземпляр с сильной ссылкой, поделитесь соответствующим кодом.

Ответ от https://stackoverflow.com/users/205185/duncan-c является полностью правильным, если только нет другого кода, который влияет на представление NextViewController и ссылку на vc: ViewController

Я изменил viewController на SenderViewController, но не повезло, и отправитель и получатель подключены через контроллер навигации. Т.е., если я нажимаю кнопку на отправителе, получатель приходит через push-переход. моя цель состояла в том, чтобы, так как это вызвало IBAction, тогда второй контроллер представления осуществил бы функцию, подтвержденную касанием. спасибо за Ваш ответ. Многому научился:)

Из-за этого комментария вам необходимо реализовать метод prepareForSegue() в вашем ViewController (оригинальный) и установить там свойство vc «следующего» контроллера представления вместо = ViewController() в «следующем», чтобы сделать расширение включенным ViewController:

extension ViewController {
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let nextController = segue.destinationViewController as! NextViewController
        nextController.vc = self
    }
}

Объяснение по комментарию:

Вы получаете новый экземпляр NextViewController с новым экземпляром ViewController, созданным в его инициализации (вместо передачи ему исходного экземпляра ViewController). Вот где вы можете получить странное поведение с делегированием.

0 голосов
/ 09 сентября 2018

слабая переменная vc: ViewController? = ViewController () Удалите слабый для vc, он освободит память контроллера представления после исчезновения

0 голосов
/ 08 сентября 2018

Для меня это похоже на проблему с управлением памятью.

Первая проблема: создание контроллера представления с инициализатором по умолчанию, таким как ViewController(), почти никогда не является правильным решением. потому что у него не будет никакого содержимого просмотра.

Вы не объясняете, как ваши NextViewController и ваши ViewController создаются и отображаются.

Похоже, что NextViewController имеет слабую ссылку на ViewController, и точка делегата ViewController также является слабой (ссылки на делегатов почти всегда должны быть слабыми.)

Эта строка:

weak var vc:ViewController? =  ViewController()

заставит NextViewController создать экземпляр ViewController, который никому не принадлежит, поэтому он будет немедленно освобожден, а переменная vc вернется к нулю. К тому времени, когда вы доберетесь до NextViewController viewDidLoad, vc станет нулевым, поэтому необязательное связывание в строке vc?.delegate = self ничего не сделает.

NextViewController переменная vc почти наверняка должна быть сильной ссылкой, а не слабой, но вы не показываете, как ViewController когда-либо отображается на экране, поэтому неясно, что вы пытаюсь сделать.

...