2014-07-12 18 views
5

Moje globalne Swapy nie są deinicjalizowane.Swift Deinitialization of Globals

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") 

Używam tego w osobnym pliku binarnego (bo apparently the playground has issues with deinit) z wyłączonymi optymalizacje, korzystając 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 

Uwaga brakujące Globalny jest deinitialized.

Nie mogę nawet dowiedzieć się, czy jest to oczekiwane zachowanie lub błąd, więc jeśli jest to pierwsze, docenione zostaną odniesienia do odpowiedniego legalese.

+0

Po co globalnie reinicjować? To własność skutecznie, prawda? – Woodstock

+0

Oba aktualne odpowiedzi wspominają, że nie jest to całkowicie nieoczekiwane, biorąc pod uwagę podstawową implementację. Jak stwierdziłem w pytaniu, jeśli tak jest, to miałem nadzieję na bardziej jednoznaczny cytat. Powodem, dla którego jest to problem, jest to, że globalny może śledzić jakiś zasób (plik, połączenie z bazą danych itp.), A biorąc pod uwagę obecne zachowanie, obowiązek byłby na programerze, aby upewnić się, że nie ma takich "właścicieli zasobów" jako globalny. – Manav

Odpowiedz

4

wygląda dobrze do mnie ... na zakończenie jest zwalniane app nic - nie ma sensu


deinit jest przeznaczona tylko do wolnej pamięci i usunąć obserwatorów i inne rzeczy - na zakończenie procesu choć jest to dosyć „nieużyteczny” jako pamięć procesu „zostaną usunięte” jakikolwiek

==>

sposób:

nigdy kłaść ale zarządzania pamięcią/obserwatora podobne rzeczy w deinit

Jeśli potrzebujesz specjalnej metody stop - napisać i nazywają to wyraźnie przed wyjściem procesowi

+0

Zgadzam się - uważamy, że nie powinniśmy zatrzymywać żadnych "właścicieli zasobów" jako obiektów globalnych, jeśli polegamy na ich nazwie dezinicjantów. Miałem jednak nadzieję na cytat :), ponieważ nie musi tak być we wszystkich językach. Na przykład C++ (pozornie jeden z wpływów na Swift) wywołuje destruktory dla obiektów globalnych. – Manav

4

myśleć o ostatniej linii kodu, jak:

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

var person = Person(name: "Global") 

exit(0) 

Od person nie jest ustawiony na inną wartość, nigdy ARC zmniejsza liczbę zachować przed wyjściem.

Swift działa jak C programu w tym wykonaniu po prostu kończy a następnie wszystko pamięć przydzielona do procesu jest zwracana w jednym cyklu.

To różni się od obsługi pamięci w trakcie wykonywania, która polega na zdarzeniach w trakcie procesu w celu zwolnienia pamięci. Ponieważ cała operacja programu została całkowicie zatrzymana, nie ma wątku do uruchomienia deinit.

Podsumowując, jest tak, jak powinno być.

+0

Ponieważ Swift ma być wyjątkowo bezpieczny w pracy, można rozsądnie oczekiwać, że uruchomi on deinicjyty przed (regularnym) rozwiązaniem. (Oczywiście, jeśli "zabijesz -9", nic nie da się zrobić.) – Raphael