2016-03-23 12 views
7

Właśnie bawiłem się przeciekami i starałem się je stworzyć celowo. Tak, to jest głupie nawet zrobić coś takiego:Wycie wykryto w instrumentach między dwoma lokalnymi vars

class LeakingObjectA{ 

    var strongRefToB:LeakingObjectB? 

    deinit{ print("LeakingObjectA deinit")} 
} 

class LeakingObjectB{ 

    var strongRefToA:LeakingObjectA? 

    deinit{ print("LeakingObjectB deinit")} 
} 

to jest w porządku dla celów naukowych, a to tworzy silne cyklu odniesienia.

Teraz wewnątrz didMoveToView Oświadczam lokalnych stałe i dokonać wyciek takiego:

override func didMoveToView(view: SKView) { 

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

     a.strongRefToB = b 

     b.strongRefToA = a 
    } 

Po przejściu do innej sceny, scena na deinit nazywa się poprawnie, ale deinits z a i b przypadkach nie są faktycznie nazywany.

Także mówię wyciek bo to jest rzeczywiście wykryto w instrumentach jako wyciek:

enter image description here

Teraz jest różnica między tym, co Instruments wykryć jak wyciek, jeśli Oświadczam tych dwóch lokalnych vars jak właściwości sceny:

class GameScene:SKScene { 

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

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

oczywiście w tym przypadku, scena na deinit nazywa się także po przejściu, i tak samo jak powyżej, deinits od a i b wystąpienia nie są wywoływane (z powodu silnego cyklu odniesienia).

Wciąż jest to nie wykryte jako wyciek w przyrządach ... Jakie byłoby rozsądne wytłumaczenie tego?

+0

Czy pytasz, dlaczego jest to przeciek, gdy masz je jako zmienne lokalne, ale nie wtedy, gdy czynisz je globalnymi dla klasy? Czy nie byłoby tak dlatego, że twoja instancja jest nadal dostępna z jakiegoś referencji. Ale zmienne lokalne tego nie robią. (Gdybyś potraktował to jak drzewo, twoje zmienne sceniczne nadal mają dołączoną gałąź, ale twoje zmienne lokalne są po prostu unoszone gdzieś w przestrzeni) – Knight0fDragon

+0

@ Knight0fDragon Hm, ale tak nie jest w tym przypadku, jeśli rozumiem cię poprawnie. .. "Drzewo" (które jest sceną) zniknęło tutaj po przejściu, a także nazywa się deinit sceny, więc silne odniesienia od sceny do tych instancji również minęły. I oczywiście, te instancje nadal istnieją (deinit z nich nie jest nazywany), ale nie jest to wykrywane jako przeciek, jak w przypadku lokalnych zmiennych. – Whirlwind

+0

Och, źle to przeczytałem, myślałem, że powiedziałeś, że deinit sceny nie został wywołany, więc w obu przypadkach scena już nie istnieje. ale same obiekty wciąż istnieją, dlaczego miejscowi są uważani za przecieki, a globale nie? jest tutaj pytanie. W tym momencie jedyną różnicą, o której mogę pomyśleć, jest to, że locale są na stosie, ale globale są w kupce. – Knight0fDragon

Odpowiedz

0

Nie mogłem wykonać replikacji, używając poniższego kodu. Scena tymczasowa została odpowiednio zdezynfekowana i pojawiły się obydwa instrumenty.

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

Dzięki za wypróbowanie tego. Z jakich systemów iOS i Xcode korzystasz? – Whirlwind

+0

Xcode 7.3 i iPad 2 symulator w/iOS 9.3 – Kevin

+0

Jestem na Yosemite, iOS 9.1 i Xcode 7.1.1, więc może się zdarzyć, że to zachowanie jest związane z tym faktem. Mimo to muszę wypróbować twój kod i zobaczyć, jakie wyniki otrzymam, ponieważ twój kod nie jest tak naprawdę taki jak mój (jest podobnie, ale przejście jest inne). Jakiego rodzaju projektu faktycznie użyłeś (szablon gry SpriteKit lub coś innego)? – Whirlwind