在没有初始化新对象的情况下调用UIViewController

时间:2015-10-20 05:07:28

标签: ios swift uiviewcontroller storyboard

我使用Swift 2.0在iOS 9中构建。我的初始UIViewController是我的菜单屏幕。它包含以下代码:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let id = segue.identifier where id == "GamePlayScene" {
        self.gameVC = segue.destinationViewController as? GameViewController
        self.gameVC!.delegate = self
        if let s = sender as? GKTurnBasedMatch {
            self.gameVC!.match = s
        }
    }
}

当segueing到我的GameViewController时,以下init在prepareForSegue被调用之前运行:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    GKLocalPlayer.localPlayer().registerListener(self) // I only want this once
}

在故事板中,我的GameViewController有一个"菜单"连接到视图控制器的退出小部件的按钮,它按预期展开到菜单。但每当我再次执行segue时,init再次被调用,所以我现在有多个GameViewControllers。我认为这会减慢我的应用程序,因为我使用的是SKScenes。 如何在没有每次创建新对象的情况下执行segue?

func player(player: GKPlayer, receivedTurnEventForMatch match: GKTurnBasedMatch, didBecomeActive: Bool) {
    if didBecomeActive {
        // This event is what activated the app, so the user wants it right meow
        GameKitHelper.sharedInstance.match = match
        performSegueWithIdentifier("GamePlayScene", sender: match)
    }
}

2 个答案:

答案 0 :(得分:3)

您可以将GameViewController存储在一个单身中,这样只需要创建一次。由于视图控制器仅在保存处理时间时初始化。对于使用两个视图控制器(例如游戏)的应用程序来说,这可能是一个很好的性能优化,需要经常在两者之间来回切换。

这样做的方法是创建一个新的Swift类,并将其作为共享实例访问,其中第二个视图控制器存储在私有属性中。如果尚未初始化第二个视图控制器,则将对其进行实例化。进一步检索视图控制器返回存储的视图控制器,从而消除了初始化视图控制器的需要。创建视图控制器,存储它并返回它的操作由公共可访问的计算属性的getter处理。

以下是该类的代码:

<强> Singleton.swift:

import Foundation
import UIKit

class Singleton {

    static let sharedInstance = Singleton()

    var gameViewController: GameViewController {
        get {
            if self.storedViewController == nil {
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                self.storedViewController = 
                     storyboard.instantiateViewControllerWithIdentifier("GameViewController") as? GameViewController
            }

            return self.storedViewController!
        }
    }

    private var storedViewController: GameViewController?

}

要使用此功能,必须使用显示游戏视图控制器的showViewController方法,而不是使用segue。

在第一个视图控制器中,我有:

@IBAction func buttonWasPressed(sender: AnyObject) {
    let vc = Singleton.sharedInstance.gameViewController
    navigationController?.showViewController(vc, sender: self)
}

第二个控制器(GameViewController)现在只会创建一次并在每次按下按钮时重复使用在第一个视图控制器上。

答案 1 :(得分:1)

GKLocalPlayer.localPlayer().registerListener(self) // I only want this once

使代码行在应用程序的生命周期内仅运行一次的方法是使用dispatch_once