6

Trong OS X v10.11 beta release notes là gì, tôi thấy như sau:một "phi yếu zeroing tham khảo"

NSNotificationCenter và NSDistributedNotificationCenter không còn gửi thông báo cho các quan sát viên đã đăng ký có thể được deallocated. Nếu người quan sát có thể được lưu trữ như là một tham chiếu zeroing yếu, lưu trữ cơ bản lưu trữ người quan sát như là một tham chiếu yếu zeroing. Ngoài ra, nếu đối tượng không thể được lưu trữ yếu (vì nó có cơ chế giữ lại/giải phóng tùy chỉnh sẽ ngăn thời gian chạy có thể lưu trữ đối tượng yếu) đối tượng được lưu trữ dưới dạng tham chiếu zeroing không yếu. Điều này có nghĩa là các nhà quan sát không bắt buộc phải hủy đăng ký theo phương thức deallocation của họ. [nhấn mạnh mỏ]

Điều này không có ý nghĩa với tôi. Nếu nó là một tham chiếu không yếu, nó sẽ không phải là một tài liệu tham khảo mạnh mẽ, sau đó? Vì vậy, NSNotificationCenter vẫn sẽ là một chủ sở hữu, vì vậy đối tượng sẽ không deallocate (cho đến khi chưa đăng ký theo cách thủ công), do đó, nó vô nghĩa trong bối cảnh này để nói rằng nó "zeroing".

Nếu điều này đề cập đến một loại tham chiếu __unsafe_unretained, thì câu hỏi là… làm cách nào NSNotificationCenter tránh nhắn tin cho một zombie?

Trả lời

4

Câu trả lời cho điều này nằm sâu trong thời gian chạy mục tiêu-c và cách các biến số thực sự hoạt động như thế nào __weak. Để giải thích, chúng ta hãy nhìn một chút tại objc_weak.mm:

id 
weak_read_no_lock(weak_table_t *weak_table, id *referrer_id) 
{ 
    ... 

    if (! referent->ISA()->hasCustomRR()) { 
     if (! referent->rootTryRetain()) { 
      return nil; 
     } 
    } 
    else { 
     BOOL (*tryRetain)(objc_object *, SEL) = (BOOL(*)(objc_object *, SEL)) 
      object_getMethodImplementation((id)referent, 
              SEL_retainWeakReference); 
     if ((IMP)tryRetain == _objc_msgForward) { 
      return nil; 
     } 
     if (! (*tryRetain)(referent, SEL_retainWeakReference)) { 
      return nil; 
     } 
    } 

    return (id)referent; 
} 

Như bạn có thể thấy, khi tùy chỉnh -retain-release phương pháp được sử dụng bởi một đối tượng, nó không được bảo đảm rằng họ hỗ trợ tài liệu tham khảo yếu ở tất cả (cũng lưu ý rằng bạn có thể sử dụng một đối tượng hoàn toàn khác cho các tham chiếu yếu của một đối tượng, mặc dù đó là một chủ đề cho một thời điểm khác).

Điều này là do các tham chiếu yếu được làm sạch bởi objc_destructInstance, gọi số objc_clearDeallocating, gọi weak_clear_no_lock.

Hiện tại, objc_destructInstance KHÔNG bắt buộc phải được gọi bởi triển khai đối tượng tùy chỉnh, mặc dù hầu hết các đối tượng sẽ gọi nó. Do đó, thời gian chạy cho phép bạn thực hiện phương thức -allowsWeakReference (và retainWeakReference) để vô hiệu hóa các tham chiếu yếu tới đối tượng của bạn, trong trường hợp đó rất có thể là không bị xóa bởi swizzling -dealloc trên đối tượng. Tất nhiên, đây là tất cả các chi tiết thực hiện, vì vậy NSNotificationCenter có thể có cách sáng tạo riêng để làm mọi thứ, nhưng đó là dự đoán tốt nhất của tôi mà không cố gắng tháo rời NSNotificationCenter.

+0

Đối với một thực hiện ví dụ về các loại swizzling Tôi đang đề cập đến, hãy xem [MAZeroingWeakRef] (https://github.com/mikeash/MAZeroingWeakRef/). –

+0

Câu trả lời rất kỹ lưỡng, và chính xác loại giải thích mà tôi đã hy vọng. Cảm ơn! – natevw

0

Tuyên bố thuộc tính mạnh làm cho thuộc tính đó trở thành tham chiếu mạnh mẽ. Khai báo nó là yếu sử dụng một tham chiếu yếu zeroing.Các unsafe_unretained modifier sử dụng một yếu tham chiếu không zeroing

ngắn gọn: non-weak zeroing reference == unsafe_unretained refernce

tham khảo:

https://mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html http://www.jessesquires.com/UIKit-changes-in-iOS-9/

+0

Câu hỏi này khác với trường hợp phổ biến hơn. Không phải "một tham chiếu yếu không zeroing" là gì. Câu hỏi đặt ra ở đây là "tham chiếu zeroing không yếu" là gì. – natevw

+0

Bạn có nghĩa là chúng khác nhau? – Proton

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