2014-07-12 7 views
5

Meine Swift Globals werden nicht deinitialisiert.Schnelle Deinitialisierung von Globalen

class Person { 
    let name: String 
    init(name: String) { 
    self.name = name 
    println("\(name) is being initialized") 
    } 
    deinit { 
    println("\(name) is being deinitialized") 
    } 
} 

func local() { 
    let person = Person(name: "Local") 
} 

local() 

var personp: Person? = Person(name: "Optional Global") 
personp = nil 

var person = Person(name: "Global") 

ich dies in einem eigenständigen binären leite (weil apparently the playground has issues with deinit) mit deaktiviert Optimierungen, mit Xcode6-Beta3:

> xcrun swift -O0 arc.swift && ./arc 
Local is being initialized 
Local is being deinitialized 
Optional Global is being initialized 
Optional Global is being deinitialized 
Global is being initialized 

Notiere die fehlende Globale wird deinitialisiert wird.

Ich kann nicht einmal herausfinden, ob dies erwartetes Verhalten oder ein Fehler ist, also wenn es der ehemalige ist, dann werden Verweise auf die relevante Rechtsprache geschätzt.

+0

Warum sollte global reinit werden? Es ist eine Eigenschaft, nicht wahr? – Woodstock

+0

Beide aktuellen Antworten erwähnen, dass dies angesichts der zugrunde liegenden Implementierung nicht völlig unerwartet ist. Wie ich in der Frage gesagt habe, wenn das der Fall ist, dann habe ich auf ein definitiveres Zitat gehofft. Der Grund, warum dies ein Problem ist, ist, dass das Globale irgendeine Art von Ressource (Datei, Datenbankverbindung usw.) verfolgen kann, und angesichts des aktuellen Verhaltens wäre es für den Programmierer wichtig sicherzustellen, dass keine solchen "Ressourcenbesitzer" gehalten werden als global. – Manav

Antwort

4

es mir sieht gut aus ... auf die App nichts enden wird aufgehoben - es keinen Sinn


deinit nur um Speicher freizugeben gemeint ist, und entfernen Beobachter und Sachen - obwohl der Prozess nach Beendigung das ist irgendwie 'nutzlos', da der Prozess Speicher sowieso 'abgewischt werden'

==>

sO:

nie etwas anderes als Speicherverwaltung/Beobachter related stuff in deinit

setzen Wenn Sie eine eigene Stop-Methode benötigen - ein explizit schreiben und rufen, bevor der Prozess

+0

Ich stimme zu - es scheint, dass wir keine "Ressourcenbesitzer" als globale Objekte behalten sollten, wenn wir uns darauf verlassen, dass ihr Name aufgerufen wird. Ich habe auf ein Zitat gehofft :), weil das nicht unbedingt in allen Sprachen der Fall ist. Zum Beispiel ruft C++ (scheinbar einer der Einflüsse auf Swift) Destruktoren für globale Objekte auf. – Manav

4

Denken Sie an die letzte Zeile des Codes zu verlassen, wie:

var personp: Person? = Person(name: "Optional Global") 
personp = nil 

var person = Person(name: "Global") 

exit(0) 

Da person nie auf einen anderen Wert gesetzt, ARC nimmt nie die Zählung vor der Ausfahrt zu halten.

Swift wie ein C-Programm in dieser Ausführung funktioniert einfach beendet und dann alle Speicher zu dem Prozess zugeordnet sind, in einem Durchlauf zurückgegeben.

Dies unterscheidet sich sehr von der Ausführung von Speicher in der Ausführung, die auf In-Process-Ereignisse zum Freigeben von Speicher angewiesen ist. Da die gesamte Ausführung des Programms vollständig gestoppt wurde, gibt es keinen Thread zum Ausführen der deinit.

Also zum Schluss, das ist so, wie es sein sollte.

+0

Da Swift besonders sicher arbeiten soll, könnte man vernünftigerweise erwarten, dass es vor der (regulären) Beendigung Deinitializer laufen lässt. (Natürlich, wenn Sie "-9" töten, kann nichts getan werden.) – Raphael