2015-04-22 3 views
2

Я использую NSNotificationCenter, чтобы контролировать таймер в SpriteKit. Код запускается нормально, когда я впервые вхожу в SKScene, но когда я пытаюсь повторно ввести SKScene, я получаю ошибку EXC_BAD_ACCESS. Я думаю, что это связано с функцией removeObserver. Я не уверен, когда удалять наблюдателя, я пытался сделать это в функции prepareForSegue без успеха. Мой ViewController выглядит следующим образом:NSNotificationCenter, вызывающий ошибку EXC_BAD_ACCESS с помощью SpriteKit

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 для Swift:

class GameScene: SKScene { 

    // ... 

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

Если вы планируете добавить и удалить эту сцену из ваше мнение несколько раз вам также следует рассмотреть возможность удаления ваших наблюдателей в willMoveFromView(_:).

Смежные вопросы