2015-04-22 81 views
2

我正在使用NSNotificationCenter試圖控制SpriteKit中的計時器。當我第一次進入SKScene時代碼運行良好,但是當我嘗試並重新進入SKScene時,我得到一個EXC_BAD_ACCESS錯誤。我認爲這與removeObserver函數有關。我不確定何時刪除觀察者,我試圖在prepareForSegue函數中做到這一點,但沒有成功。我的viewController如下:NSNotificationCenter導致與SpriteKit EXC_BAD_ACCESS錯誤

class JobStartedViewController: UIViewController { 



var titleOfJob: String = "" 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let skView = self.view as! SKView 

    let scene:SKScene = GameScene.init(size: skView.bounds.size) 

    NSNotificationCenter.defaultCenter().postNotificationName("stopTimerNotification", object: nil) 
    NSNotificationCenter.defaultCenter().postNotificationName("startTimerNotification", object: nil) 

    /* Sprite Kit applies additional optimizations to improve rendering performance */ 
    skView.ignoresSiblingOrder = true 

    /* Set the scale mode to scale to fit the window */ 
    scene.scaleMode = .AspectFill 

    skView.presentScene(scene) 
} 

,並添加我觀察到我的GameScene.swift如下:

class GameScene: SKScene { 


override func didMoveToView(view: SKView) { 


    NSNotificationCenter.defaultCenter().addObserver(self, selector: "stopTimerInBackground:", name:"stopTimerNotification", object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "startTimerInBackground:", name:"startTimerNotification", object: nil) 
+0

您需要刪除'deinit'中的觀察者。 –

回答

5

這裏是事件的可能流量:

  1. 您呈現JobStartedViewController,它會創建場景並將其添加到視圖中,觸發didMoveToView(_:)並添加兩個觀察者。
  2. 您關閉視圖控制器或從SKView中刪除場景。在不久之後的某個時候,沒有更強烈的引用到場景並且它被釋放。 此時,通知中心仍然存在不安全的引用。
  3. 您提出另一個JobStartedViewController或以其他方式發佈stopTimerNotification通知。
  4. NSNotificationCenter嘗試在解除分配的場景上執行選擇器並崩潰您的應用程序。

通常的做法使用NSNotificationCenter時是刪除您的觀察者在dealloc方法的Objective-C或雨燕deinit方法:

class GameScene: SKScene { 

    // ... 

    deinit { 
     NSNotificationCenter.defaultCenter().removeObserver(self) 
    } 
} 

如果您計劃添加和刪除場景您的觀點多次,您還應該考慮在willMoveFromView(_:)中刪除您的觀察員。

相關問題