避免创建多个 ViewController 实例,iOS Swift

use*_*776 5 uiviewcontroller uinavigationcontroller ios swift swift3

在 AppDelegate 中,每当收到 VoIP 呼叫(推送通知)时都会调用以下函数,从而创建“VideoCallViewController”的多个实例

我使用了 deinit(在 VideoCallViewController 中),如下所示,在创建“VideoCallViewController”的新实例之前检查“VideoCallViewController”的前一个实例是否被取消初始化,令我惊讶的print("Deinitializing VC)是没有被调用,离开了实例在记忆中。

如果 AppDelegate 中已存在 VideoCallViewController 的实例,我该如何显示 VideoCallViewController 及其导航控制器。

在 VideoCallViewController 中

deinit {
  print("Deinitializing VC)
}
Run Code Online (Sandbox Code Playgroud)

在 AppDelegate 中

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    videoVC = storyboard.instantiateViewController(withIdentifier: "VideoCallViewController") as! VideoCallViewController

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = videoVC
    self.window?.makeKeyAndVisible()

}
Run Code Online (Sandbox Code Playgroud)

dvp*_*rov 1

可能的解决方案:创建单例,保存对可为空窗口的引用,负责视频通话流程。通知时更改可见窗口。通话结束 - 返回应用程序主窗口。

EG:

class VideoCallManager {
    //MARK: - Singleton
    static let sharedInstance = VideoCallManager()
    private init() {}

    private var videoCallWindow: UIWindow?

    func navigateToVideoCallViewController() {
        if let window = self.videoCallWindow, window.keyWindow {
             //VideoCallViewController is displayed at the moment.
             return
        }

        videoCallWindow = UIWindow.init(frame: UIScreen.mainScreen().bounds)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        videoVC = storyboard.instantiateViewController(withIdentifier: "VideoCallViewController") as! VideoCallViewController

        self.videoCallWindow?.rootViewController = videoVC
        self.videoCallWindow?.makeKeyAndVisible()
    }

    func returnToWindowOfAppDelegate() {
        if let window = self.videoCallWindow, window.keyWindow {
            (UIApplication.sharedApplication().delegate as? AppDelegate)?.window?.makeKeyAndVisible()

            self.videoCallWindow = nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你的方法看起来像:

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
    VideoCallManager.sharedInstance.navigateToVideoCallViewController()
}
Run Code Online (Sandbox Code Playgroud)