2015-05-26 15 views
6

Tôi hiện đang theo dõi Apple Documentation. Đây là câu hỏi của tôi:ARC (tính năng tham khảo tự động) trong hành động

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 
    } 
} 

Sau reference1 bằng nil, ARC deallocates dụ và in "John Appleseed is being deinitialized"

không nên nó được deallocates sau reference3 = nil?

+0

@JakubVano Để biết thêm thông tin tôi đang chạy mã này trong viewDidLoad() phương pháp. Tuy nhiên reference3 không phải là nil, trình biên dịch deallocates dụ ngay cả tham chiếu Strong tồn tại. – ridvankucuk

+0

Ảnh chụp màn hình đó thêm lộn xộn, không rõ ràng. – nhgrif

+0

Bạn xác định thời điểm * chính xác * mà 'deinit' xảy ra như thế nào? Tôi hy vọng nó sẽ được gọi ngay sau khi phương thức trả về (và chắc chắn không phải là một lúc sau). Nó có thể được gọi trước đó do một số loại tối ưu hóa, nhưng nó chắc chắn sẽ không treo xung quanh sau khi phương thức trả về. – nhgrif

Trả lời

6

Vấn đề ở đây là một vấn đề phạm vi. Chúng ta có thể tìm hiểu thêm với các điểm ngắt.

Ở đây, chúng tôi dừng lại trước khi chúng tôi khởi tạo reference1.
Tất cả các biến là dự kiến ​​nil:

enter image description here

Và sau khi khởi tạo của reference1?

enter image description here


Được rồi, chúng ta hãy bỏ qua mong muốn sau khi reference2reference3 được thiết lập:

enter image description here

Cả ba biến trỏ đến vị trí bộ nhớ giống nhau, và chúng ta có thể thấy initializer chỉ chạy một lần. Tất cả đều trỏ đến cùng một vị trí.

Hãy bước về phía trước:

enter image description here

reference1 hiện đang trỏ đến None. Đó là nil. Phương thức m1hod deinit không được gọi và in thông điệp của nó.

Hãy bước tiến một số chi tiết:

enter image description here

Bây giờ reference1reference2 đều dự kiến ​​nil. Các tuyên bố println tôi đã thêm được gọi. Nhưng deinit không chạy và reference3 không phải là nil.

Bước tiếp theo là tất cả các bước ra khỏi phương pháp.Khi chúng tôi ra khỏi phương pháp, các biến được ra khỏi phạm vi và deinit được gọi là:

enter image description here

1

Nó được deallocating bởi vì, trình biên dịch có thể nhận ra rằng không có sử dụng nhiều hơn các đối tượng tạo ra tại địa phương. Ví dụ trong mã dưới đây sau khi thực hiện phương thức viewDidLoadPerson sẽ bị hủy cấp phát vì không có ai sử dụng đối tượng người trong tương lai.

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

Nếu bạn muốn giữ lại các đối tượng thì bạn cần phải tạo reference3 như property như sau:

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

Tôi có thể truy cập ** reference3? .name ** ngay cả khi ** reference3 ** không phải là toàn cục. – ridvankucuk

+0

Không có ứng dụng nào sẽ không biên dịch nếu bạn khai báo tham chiếu3 trong didLoad và sử dụng trong didAppear. – kmithi

Các vấn đề liên quan