2015-10-20 45 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

相关问题