iOS 解除 segue 中断 protocol/delegate。为什么?

iOS unwind segue breaking protocol/delegate. Why?

我有一个 iPhone 应用程序,可以显示有关在 kiosk-like 设备上播放的视频的信息。信息亭是 运行 一个 python 脚本,它通过 MQTT 发送视频信息。

iPhone使用CocoaMQTT监听视频信息。当收到信息(标题等)时,应用程序会在 NowPlayingVC 中以模态形式显示它,并带有来自 MenuVC 的转场。视频播放完毕后,信息亭会发送一条 'finished' 消息,并且 NowPlayingVC 会触发到 MenuVC 的展开转场。此过程第一次运行良好,但第一次后失败。

为了处理 MQTT 通信,我使用了一个名为 MQTTManager 的模型的共享实例,它定义了各种协议函数,这些函数被调用以响应信息亭发布的 MQTT 消息。这些功能之一是 vhPlayingVideoInfoLoaded,它提供有关从自助服务终端发送的正在播放的视频的信息(例如 MQTT Manager 呼叫 self.delegate?.vhPlayingVideoInfoLoaded!(description: String(descriptParts[1]), videoFile: String(descriptParts[0]))

第一次通过后,unwind segue MQTTManager 做了它应该做的,但是 MenuVCMQTTManager 的代表停止响应作为代表 - 它就像如果 unwind segue 中断了委托。

作为一项实验,我用从 NowPlayingVCMenuVC 的故事板转场替换了展开转场,并且第一次和之后的一切都完全正常。这种方法的问题在于,最终会得到一大堆 memory-consuming 的 VC,这会让用户感到困惑。

谁能解释一下为什么 unwind segue 会破坏 protocol/delegate?有办法解决吗?我很乐意提供代码,但我猜测 self-taught,我的方法遗漏了一个明显的问题。

我已经厌倦了通过在各种视图函数中放置 mqtt.delegate=self 来刷新委托,但这没有效果。

如有任何想法,我们将不胜感激,谢谢。我正在使用 Xcode 13.3 并定位 iOS 13.

假设:

  • 你的“NowPlayingVC 模态”segue 有一个标识符“didStart”
  • 你的 unwind segue 有一个标识符“unwind”

您将拥有以下几行代码:

class MenuVC: UIViewController, MQTTDelegate {
    
    let mqtt = MQTTObject.sharedInstance
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // set mqtt delegate to self
        mqtt.delegate = self
    }
    
    // mqtt sends a "player started playing" to its delegate (which is self)
    func didStart() {
        performSegue(withIdentifier: "didStart", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? NowPlayingVC {
            // set mqtt delegate to the segue destination controller
            mqtt.delegate = vc
        }
    }
    
    @IBAction func unwind( _ seg: UIStoryboardSegue) {
        // set mqtt delegate to self again
        mqtt.delegate = self
    }
}

class NowPlayingVC: UIViewController, MQTTDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // mqtt sends a "player finished playing" to its delegate (which is self)
    func didFinish() {
        performSegue(withIdentifier: "unwind", sender: self)
    }
}