2016-03-23 12 views
7

Stavo solo giocando con perdite e ho cercato di crearne uno intenzionalmente. Quindi, anche se è stupido fare qualcosa di simile a questa:Perdita rilevata in Strumenti tra due vars locali

class LeakingObjectA{ 

    var strongRefToB:LeakingObjectB? 

    deinit{ print("LeakingObjectA deinit")} 
} 

class LeakingObjectB{ 

    var strongRefToA:LeakingObjectA? 

    deinit{ print("LeakingObjectB deinit")} 
} 

va bene per gli scopi scientifici, e questo crea un ciclo di riferimento forte.

Ora all'interno didMoveToView dichiaro costanti locali e fare una perdita come questa:

override func didMoveToView(view: SKView) { 

     let a = LeakingObjectA() 
     let b = LeakingObjectB() 

     a.strongRefToB = b 

     b.strongRefToA = a 
    } 

Dopo il passaggio a un'altra scena, della scena deinit si chiama correttamente, ma deinits da a e b casi non sono effettivamente chiamato.

Anche io dico Leak perché questo è in realtà rilevato in strumenti come una perdita:

enter image description here

Ora c'è una differenza tra quello che Instruments rilevare come la fuga se dichiaro queste due Vars locali come proprietà di una scena:

class GameScene:SKScene { 

    let a = LeakingObjectA() 
    let b = LeakingObjectB() 

    //...later in didMoveToView method I make a strong reference cycle like from the example above 
} 

Naturalmente in questo caso, il deinit scena è chiamato così dopo la transizione, e come sopra, 012.da a e b istanze non chiamate chiamate (a causa del ciclo di riferimento intenso).

Ancora, questo è non rilevato come perdita in Strumenti ... Quindi quale sarebbe la spiegazione ragionevole per questo?

+0

Stai chiedendo perché è una perdita quando li hai come variabili locali, ma non quando li rendi globali alla classe? Non sarebbe perché la tua istanza è ancora accessibile da qualche riferimento in attesa. Ma le tue variabili locali no. (Se dovessi trattare questo come un albero, le tue variabili di scena hanno ancora un ramo collegato, ma le tue variabili locali stanno semplicemente fluttuando nello spazio da qualche parte) – Knight0fDragon

+0

@ Knight0fDragon Hm, ma questo non è il caso qui se ti capisco correttamente. .. "L'albero" (che è la scena) è andato qui dopo la transizione, e anche il deinit della scena è chiamato, quindi anche i riferimenti forti dalla scena a quelle istanze sono andati. E ovviamente, quelle istanze sono ancora lì (non viene chiamato da loro), ma questo non viene rilevato come una perdita, come nel caso delle vars locali. – Whirlwind

+0

Oh, ho letto male, pensavo avessi detto che il deinit della scena non veniva chiamato, quindi in entrambi i casi la scena non esiste più. ma gli oggetti stessi esistono ancora, perché gli abitanti del luogo considerano le fughe e i globali no? è la domanda qui. A questo punto l'unica differenza che posso pensare è che i locali sono in pila, ma i globali sono nell'heap – Knight0fDragon

risposta

0

Non è stato possibile replicare utilizzando il codice riportato di seguito. La scena temporanea è stata deinitializzata in modo corretto e sia LeakingObjectA sia LeakingObjectB sono visualizzati nello strumento delle perdite.

class LeakingObjectA { 
    var strongRefToB:LeakingObjectB? 
    deinit{ print("LeakingObjectA deinit")} 
} 

class LeakingObjectB { 
    var strongRefToA:LeakingObjectA? 
    deinit{ print("LeakingObjectB deinit")} 
} 

class TempScene : SKScene { 
    let a = LeakingObjectA() 
    let b = LeakingObjectB() 

    override init() { 
     a.strongRefToB = b 
     b.strongRefToA = a 
     super.init(size: CGSizeZero) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    deinit { 
     print("Deiniting temp scene") 
    } 
} 

class ViewController { 
    var tempScene: TempScene? 
    override func viewWillAppear(animated: Bool) { 
     super.viewWillAppear(animated) 
     tempScene = TempScene() 
    } 

    override func viewWillDisappear(animated: Bool) { 
     super.viewWillDisappear(animated) 
     tempScene = nil 
    } 
} 
+0

Grazie per aver provato questo. Che cosa usi iOS e Xcode? – Whirlwind

+0

Simulatore Xcode 7.3 e iPad 2 con iOS 9.3 – Kevin

+0

Sono su Yosemite, iOS 9.1 e Xcode 7.1.1 in modo che possa accadere che questo comportamento sia correlato a tale fatto. Tuttavia, devo provare il tuo codice e vedere quali risultati otterrò perché il tuo codice non è proprio uguale al mio (è simile, ma la transizione è diversa). Che tipo di progetto hai usato in realtà (modello di gioco SpriteKit o qualcos'altro)? – Whirlwind

Problemi correlati