2016-06-22 2 views
3

J'utilise SpriteKit dans une application iOS, et j'essaie d'initialiser la propriété camera de mon SKScene dans la méthode didMoveToView surchargée. Si je viens de l'initialiser comme ceci:SpriteKit SKCameraNode - Nil lors du déballage d'une valeur optionnelle juste après avoir affecté

override func didMoveToView(view: SKView) { 
    ... 
    self.camera = SKCameraNode() 
    self.addChild(self.camera!) 
} 

... il jette l'exception unexpectedly found nil while unwrapping an Optional value à la ligne self.addChild, mais si je fais ceci:

override func didMoveToView(view: SKView) { 
    ... 
    let camera = SKCameraNode() 
    self.camera = camera 
    self.addChild(self.camera!) 
} 

... il fonctionne très bien, aucune exception . Pourquoi ces deux façons sont-elles différentes? Y a-t-il une sorte de collecte des déchets? Ce n'est pas gênant d'utiliser le deuxième format, cela fonctionne, mais je suis curieux de savoir ce qui diffère que je suis manquant.

+0

Pouvez-vous nous montrer comment vous déclarez votre caméra dans le premier cas s'il vous plaît? – H4Hugo

+0

Voilà, j'ai supposé que la variable facultative 'camera' dans le SKScene (' self' se réfère ici à une sous-classe SKScene) pouvait être initialisée et que cette référence protégerait l'objet caméra de la récupération de place. 'self.camera' est déclaré dans les fichiers SKScene dans SpriteKit. – jaxuru

Répondre

3

La propriété camera de SKScene est définie comme weak:

weak public var camera: SKCameraNode? 

Par conséquent, comme ARC désaffecter toute instance qui ne dispose pas d'une forte référence à elle (Swift uses ARC, pas la collecte des ordures) - dès que vous lui affecter SKCameraNode(), il sera désalloué et sera donc nil. Vous procédez ensuite à forcer le déballer (que vous devriez always avoid doing), provoquant le crash.

Votre deuxième exemple fonctionne comme vous avez une forte référence à l'instance de votre appareil photo grâce à votre

let camera = SKCameraNode() 
déclaration

, ce qui empêche donc d'être désallouée alors que la référence forte pour elle existe (notez que addChild va également créer un forte référence à celui-ci).