2015-10-20 70 views
2

我正在用Swift 2.0編譯iOS 9。我有我的起始UIViewController,這是我的菜單屏幕。它包含以下代碼:在沒有初始化一個新對象的情況下繼續使用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會再次被調用,所以我現在有多個GameViewController。我認爲這是因爲我使用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) 
    } 
} 

回答

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

以致使一行代碼懸停在應用的生命週期只運行一次的方式是與dispatch_once

+0

非常有幫助的功能,謝謝。 – dem7w2

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方法,而不是使用賽格。

在第一視圖控制器我有:

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

現在將僅創建一次並重新使用的每一個按鈕被按下第一視圖控制器上的時間,第二控制器(GameViewController)。

+0

GameViewController的退出功能是否仍然有效?當我放鬆菜單時,是否有任何東西會被釋放? – dem7w2

+1

@ dem7w2我的例子使用導航控制器。當後退按鈕被按下時,視圖控制器不會被取消分配。使用此優化可能需要您更改在視圖之間導航的方式。我不相信它會支持在故事板中使用segues。但是,使用'showViewController:sender:'和'popViewControllerAnimated:'設置導航控制器相對容易。 – Daniel

+0

這比這更復雜一點,因爲還有其他屏幕,如選項和挑戰以及獨奏模式,在移動到遊戲視圖控制器之前需要看到額外的視圖。不過,'showViewController'很可能會做我所需要的,謝謝。 – dem7w2

相關問題