2015-10-31 13 views
5

Quindi ho letto diverse domande su questo argomento ma la maggior parte si trova in Objective-C e non ho trovato alcun indirizzo/risposta direttamente. Sono nuovo nella programmazione qui, quindi per favore spiegate ogni suggerimento in modo approfondito.Swift: Deallocate GameScene dopo il passaggio a una nuova scena?

Ho bisogno di capire come deallocate il mio GameScene dopo il game over è stato raggiunto. La ragione per cui ho bisogno di farlo è che dopo il game over, passo a un nuovo SKScene (il gioco sulla scena) e quando torno al GameScene, GameScene non viene resettato completamente o sto generando un nuovo GameScene ogni volta .

Dico questo perché il mio numero di fotogrammi al secondo diminuisce ogni volta che finisco la partita e ritorno al GameScene, in modo che se lo faccio abbastanza volte non posso nemmeno più giocare. Questo è un problema.

non capisco il motivo per cui questo accade perché quando ho transizione verso il mio gioco su scena, tolgo tutto, dalla mia GameScene:

self.viewController!.performSegueWithIdentifier("goToGameOver", sender: nil) 
      self.removeAllChildren() 
      self.removeAllActions() 
      self.scene?.removeFromParent() 

Ho letto anche qui: After Closing SKScene, Memory Remains High che la rimozione del SKView che contiene uno SKScene dealloca lo SKScene, così quando sia il mio GameScene e gioco sopra le scene sono di sinistra, tolgo entrambe le viste dai loro superviews come questo:

override func viewDidDisappear(animated: Bool) { 
     print("its gone") 

     self.view.removeFromSuperview() 

    } 

Ma niente ha alcun effetto sulle cornici decrescenti al secondo conteggio e il gioco continua a laggin g. Non capisco cosa non sto facendo e non riesco a capire se il problema del game over è il problema o semplicemente non sto rilasciando GameScene.

Come rilasciare il GameScene? Che altro dovrei fare?

EDIT:

mio numero di nodi e disegna conteggio rimangono circa lo stesso ogni volta che la transizione torna a GameScene, in modo che non sembra essere un problema. Ho provato a testare se deinit è stato chiamato durante le transizioni tra le scene (non ho avuto un deinit prima) utilizzando questo all'interno della classe GameScene:

} //<**End of GAMESCENE** 

    deinit { 
     print("Deinit was called") 
    } 

E nulla viene stampato in modo deinit non viene chiamato.

EDIT 2:

@alex_p Ecco quello che ho nel mio GameViewController-

class GameViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver { 

    var scene1: GameScene? 
    var scene2: GameScene? 
    var skView: SKView? 

// Action to present next Scene 
    @IBAction func nextSceneAction(sender: AnyObject) { 
     print("Next scene") 
     // Create new GameScene object 
     scene2 = GameScene(fileNamed:"GameScene") 
     // Present scene2 object that replace the scene1 object 
     skView!.presentScene(scene2) //ERROR ON THIS LINE 
     scene1 = nil 
    } 

E chiamare questo metodo dal mio GameScene in questo modo:

self.viewController.nextSceneAction(self) 

ho copiato la vostra esattamente ma sto ricevendo l'errore unexpectedly found nil while unwrapping an Optional value sulla linea commentata sopra. Deinitare nel non essere chiamato.

+0

Si può iniziare con deinit imperativo di scene. Verifica se viene chiamato durante la transizione tra le scene. Sarebbe un inizio. Se il deinit non viene chiamato, è necessario cercare i possibili cicli di mantenimento. Controlla anche i nodi e conta il conteggio. Puoi aggiornare la tua domanda con quei dati? – Whirlwind

+0

Appena aggiornato. Non penso che il deinit venga chiamato così come si fa a cercare un ciclo di conservazione? – skyguy

+0

Sì, probabilmente hai alcuni forti riferimenti alla scena ... Per iniziare dai un'occhiata a questo: http://stackoverflow.com/questions/19251337/ios-7-sprite-kit-freeing-up-memory/19253739 # 19253739. Dopo il check out, termini "auto non proprietario" e "auto debole" http://stackoverflow.com/questions/24320347/shall-we-always-use-unowned-self-inside-closure-in-swift/24320474#24320474 Spero che questo ti porti da qualche parte. – Whirlwind

risposta

0

Nel mio progetto, ho utilizzato il seguente meccanismo e ha funzionato bene. Tutti gli oggetti della mia scena SKScene erano variabili facoltative. Quando ho bisogno della nuova scena da mostrare, la creo e la regalo al SKView. Quando ho bisogno di visualizzare la nuova scena, ho impostato l'oggetto della scena oggetto precedente su nil, riducendo immediatamente il conteggio dei riferimenti di 1, e poiché in questo momento nessun oggetto non usa la mia scena, il conteggio dei riferimenti diventa zero e la scena è stato cancellato

L'oggetto SKScene è un oggetto di classe ordinario e ARC funziona con essi come con tutti gli oggetti del tipo di riferimento. Hai solo bisogno di monitorare il numero di riferimenti alla scena. Tutti sono rifiniti con le varie risorse che stavo metto in deinit di SKScene oggetto

Il semplice esempio:

A UIViewController abbiamo oggetti opzionali di GameScene:

class GameViewController: UIViewController { 
    var scene1: GameScene? 
    var scene2: GameScene? 
    var skView: SKView? 

    // Action to present next Scene 
    @IBAction func nextSceneAction(sender: AnyObject) { 
     print("Next scene") 
     // Create new GameScene object 
     scene2 = GameScene(fileNamed:"GameScene") 
     // Present scene2 object that replace the scene1 object 
     skView!.presentScene(scene2) 
     scene = nil 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Create GameScene object 
     scene = GameScene(fileNamed:"GameScene") 
     skView = (self.view as! SKView) 
     skView!.showsFPS = true 
     skView!.showsNodeCount = true 

     skView!.ignoresSiblingOrder = true 

     scene!.scaleMode = .AspectFill 

     // Present current scene 
     skView!.presentScene(scene) 
    } 
} 

A GameScene in deinit stampa del testo per dimostrare che l'oggetto sarà cancellato:

class GameScene: SKScene { 
    ... 

    deinit { 
     print("Deinit scene") 
    } 
} 
.210 uscita

Debug dopo premere il pulsante nextSceneAction:

Scena successiva

scena Deinit

+0

Sembra una buona idea. Potresti fornire un esempio di questo nel tuo codice? Ti piace come e dove impostare SKScene su una variabile opzionale e poi impostarlo su zero quando si visualizza la nuova scena? Spiacente, sono nuovo di questo – skyguy

+0

Aggiungi un esempio astratto per rispondere allo –

+0

Ho aggiornato la mia domanda. Ho provato il tuo codice ma ho ricevuto l'errore "trovato inaspettatamente nil mentre scartando un valore Opzionale" quando provo a presentare scene2. Come posso risolvere questo? – skyguy

Problemi correlati