2015-05-26 12 views
6

Obecnie śledzę numer Apple Documentation. Oto moje pytanie:Łuk ARC (automatyczne liczenie odniesienia) w akcji

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

class ViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     var reference1: Person? 
     var reference2: Person? 
     var reference3: Person? 
     reference1 = Person(name: "John Appleseed") 
     // prints "John Appleseed is being initialized 
     reference2 = reference1 
     reference3 = reference1 

     reference1 = nil 
     reference2 = nil 
    } 
} 

Po reference1 równa nil, ARC dealokuje instancji i wydruki "John Appleseed is being deinitialized"

Jeżeli nie byłoby dealokuje po reference3 = nil?

+0

@JakubVano Aby uzyskać więcej informacji Używam tego kodu w viewDidLoad metoda(). Jednak referencja 3 nie jest zerowa, ponieważ kompilator zwolni instancję, nawet jeśli istnieje odwołanie Strong. – ridvankucuk

+0

Ten zrzut ekranu dodał bałagan, a nie czystość. – nhgrif

+0

Jak określasz * dokładny * moment, w którym pojawia się 'deinit'? Oczekuję, że zostanie wywołany, gdy tylko metoda powróci (i zdecydowanie nie za chwilę). Można go nazwać wcześniej z powodu jakiejś optymalizacji, ale na pewno nie będzie się kręcić po powrocie metody. – nhgrif

Odpowiedz

6

Tutaj problemem jest kwestia zakresu. Możemy dowiedzieć się więcej o pułapkach.

Tutaj zatrzymujemy się tuż przed zainicjowaniem reference1.
Wszystkie zmienne są expectedly nil:

enter image description here

A po inicjalizacji reference1?

enter image description here


Dobra, pomińmy oczekiwać po reference2 i reference3 są:

enter image description here

wszystkich trzech zmiennych wskazują na tej samej lokalizacji pamięci, a my możemy zobaczyć inicjatora uruchomił tylko raz. Wszystkie wskazują na tę samą lokalizację. krok

Przejdźmy do przodu:

enter image description here

reference1 jest teraz skierowany do None. Jest to nil. Metoda deinit nie została wywołana i wydrukowano jej komunikat. krok

Przejdźmy do przodu kilka:

enter image description here

Teraz reference1 i reference2 są zarówno expectedly nil. Dodane przeze mnie stwierdzenia println zostały wywołane. Ale deinit nie działa, a reference3 nie jest nil.

Następnym krokiem jest przejście przez całą metodę.Raz jesteśmy z tej metody, zmienne są poza zakresem i deinit nazywa się:

enter image description here

1

Jest to dealokacja, ponieważ kompilator jest w stanie rozpoznać, że nie ma więcej możliwości używania obiektu utworzonego lokalnie. Na przykład w poniższym kodzie po wykonaniu viewDidLoad metoda zostanie usunięta, ponieważ nie ma nikogo, kto mógłby użyć obiektu osoby w przyszłości.

override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib.\ 

     var reference1: Person? 
     var reference2: Person? 
     var reference3: Person? 
     reference1 = Person(name: "John Appleseed") 
     // prints "John Appleseed is being initialized 
     reference2 = reference1 
     reference3 = reference1 

     reference1 = nil 
     reference2 = nil 

//  println(reference3?.name) 
} 

Jeśli chcesz zachować obiekt to trzeba stworzyć reference3 jak property jak poniżej:

class ViewController: UIViewController { 

    var reference3 : Person? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     var reference1: Person? 
     var reference2: Person? 

     reference1 = Person(name: "John Appleseed") 
     // prints "John Appleseed is being initialized 
     reference2 = reference1 
     reference3 = reference1 

     reference1 = nil 
     reference2 = nil 

//  println(reference3?.name) 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 
     println(reference3?.name) 
    } 

} 
+0

Mogę uzyskać dostęp do ** reference3? .name ** nawet jeśli ** reference3 ** nie jest globalna. – ridvankucuk

+0

Żadna aplikacja nie skompiluje się, jeśli zadeklarujesz reference3 w didLoad i użyjesz w didAppear. – kmithi

Powiązane problemy