2017-09-25 18 views
10

Pattern dưới đây xảy ra rất nhiều trong iOS apps:Tại sao tôi lại sử dụng bản thân mình?

class MyViewController: UIViewController { 
    let myModel = MyModel() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     myModel.foo() { [***] in 
      // use self here 
     } 
    } 
} 

class MyModel { 
    public func foo(complete:() -> Void) { 
     // do something 
     complete() 
    } 
} 

Sự đồng thuận là sử dụng một trong hai [unowned self] hoặc [weak self] ở vị trí của [***], không có chủ khi bạn có thể đảm bảo rằng tự sẽ không được bằng không tại thời điểm kết thúc và yếu khi bạn không chắc chắn tham chiếu sẽ vẫn hợp lệ.
Điều tôi không hiểu là tại sao tôi lại có thể mạo hiểm khi sử dụng unowned, có lẽ tôi chắc chắn rằng ngay bây giờ tài liệu tham khảo sẽ không bao giờ là không, nhưng điều đó có thể thay đổi trong tương lai. Tôi cũng có thể đã bỏ qua một trường hợp cạnh, những sai lầm xảy ra. Tôi có thể dễ dàng luôn luôn sử dụng yếu, và đặt một bảo vệ ở phía trên của đóng cửa để có thể sử dụng tự mà không có một! hoặc là ?.
Việc sử dụng unowned là gì? Nó có nhanh hơn bảo vệ yếu kém không? Nó là cú pháp đường? Dường như đi ngược lại triết lý bảo vệ nhà phát triển của Swift chống lại những sai lầm phổ biến có thể gây ra sự cố.

+1

Tôi không biết rất nhanh, nhưng trong các ngôn ngữ khác, các khái niệm như thế này '[unowned] 'rất quan trọng để giao tiếp với các ngôn ngữ khác như C thiếu tính tham chiếu. Mặc dù tại sao người ta sử dụng nó trong bối cảnh bạn hiện diện vượt ra ngoài tôi. –

Trả lời

9

unowned có lợi thế hiệu suất cận biên trên weak vì thời gian chạy không phải theo dõi tham chiếu để biến nó thành nil khi đối tượng biến mất.

Đối với các chu kỳ lưu giữ (tốt, chu kỳ tham chiếu mạnh), không weak cũng không unowned tạo tham chiếu mạnh mẽ (trong điều kiện ARC trước, không tăng số lần giữ) để không có nguy cơ trong chu kỳ tham chiếu, trên thực tế, đó là lý do tại sao bạn cần chỉ định weak hoặc unowned cho self khi đóng.

Ngoài ra, với unowned bạn có thể sử dụng tham chiếu dưới dạng không bắt buộc, vì vậy bạn không phải đặt bất kỳ mã nào trong phần đóng để mở nó.

Tôi luôn sử dụng weak trừ khi có lý do hiệu suất thực sự không tốt.

NB trong mã của bạn, tôi không nghĩ là cần thiết vì việc đóng không thoát ra tức là tham chiếu đến nó được thực hiện trong hàm gọi foo không tồn tại sau khi kết thúc phạm vi của foo.

+0

Chu kỳ giữ lại trong cả hai trường hợp như thế nào? , nó có liên quan ở đó trong sự khác biệt không? –

+0

Theo tôi cho bản thân yếu không có một khả năng duy nhất để giữ lại chu kỳ nhưng tôi không biết về unowned –

+0

@JonSnow 'unowned' không phải là một tham chiếu mạnh mẽ hoặc. – JeremyP

0

Theo Swit Programming Guide: Automatic Reference Counting

Một tài liệu tham khảo không có chủ dự kiến ​​sẽ luôn luôn có một giá trị. Kết quả là, ARC không bao giờ đặt giá trị tham chiếu chưa được công nhận thành 0, có nghĩa là các tham chiếu không được thừa nhận được xác định bằng cách sử dụng các kiểu không phụ thuộc.

Trong ngắn hạn, weak là các tùy chọn, trong đó unowned thì không.

+0

Nhưng tại sao? Có vẻ như sử dụng unowned chỉ giới thiệu rủi ro mà không đạt được. Tôi sẽ chơi nó an toàn hơn và luôn luôn sử dụng yếu, với một bảo vệ tự! = Nil ở đầu trang. – kevin

+2

@kevin Nếu bạn có điều kiện tiên quyết trong đối tượng của mình mà đối tượng A * không được * đối tượng ngoài B, thì hoàn toàn hợp lý đối với đối tượng A giữ nguyên 'unowned', thay vì' weak', tham chiếu đến đối tượng B. Nếu điều kiện tiên quyết bị hỏng, có thể bạn không muốn ứng dụng của mình lặng lẽ tiếp tục ở trạng thái không hợp lệ; bạn muốn nó bẫy, vì vậy bạn có thể sửa lỗi. Nó không phải là một trường hợp rủi ro, đó là một trường hợp đảm bảo bạn có một chương trình được hình thành tốt. – Hamish

+0

@Hamish +1 Điều đó có ý nghĩa. –

1

Tôi tin rằng việc sử dụng unowned sẽ tăng thêm rủi ro so với việc sử dụng bản thân yếu. Các lỗi xảy ra và một ví dụ về nó sẽ bắt đầu một cuộc gọi API trong một bộ điều khiển khung nhìn, để cho nó chờ phản hồi đến và đột nhiên xuất hiện mà bộ điều khiển xem có thể khiến nó bị xử lý (Nếu không có tham chiếu mạnh). Vào thời điểm phản hồi đến, đối tượng bộ điều khiển chế độ xem của chúng tôi sẽ biến mất và ứng dụng của chúng tôi sẽ gặp sự cố trên khuôn mặt của chúng tôi. Đó là vào chúng tôi để quyết định cái nào để sử dụng ở nơi nào.

Jeremy chỉ ra, unowned không có trách nhiệm theo dõi số lượng tham chiếu, vì vậy nó có lợi thế về hiệu suất rất yếu so với yếu và yếu.

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