2013-06-29 37 views
6

Tôi đã đọc qua tài liệu trên __block variables và suy nghĩ về các trường hợp tôi sử dụng __block. Đối với tôi, nó có vẻ như tôi cần nó trong hai trường hợp:Tại sao các biến __block không được giữ lại (Trong môi trường không phải ARC)?

  • Để đánh dấu một biến như read-write khi được sử dụng trong một khối
  • Để tránh giữ lại chu kỳ khi tham khảo tự trong một khối

Trên bề mặt nó không có vẻ như hai điều này có liên quan. Tôi xem xét thực tế là các biến __block không được giữ lại như một mẹo nhỏ mà tôi cần phải nhớ đối với trường hợp sử dụng cụ thể để tránh các chu kỳ giữ lại.

Tôi tự hỏi, có lý do quan trọng hơn về kiến ​​trúc nào không phải vì sao chúng không được giữ lại? Tôi sẽ nghĩ rằng một số từ khóa khác để cho biết điều này có thể rõ ràng hơn, để không trộn lẫn hai tính năng được liệt kê ở trên.

cập nhật -

Tôi nên đề cập đến đây là mã không sử dụng ARC. Bây giờ tôi thấy rằng các biến __block trong thực tế được giữ lại trong ARC.

+2

Bạn chỉ sử dụng '__block' cho mục đầu tiên. Bạn sử dụng '__weak', không phải' __block', để tránh các chu kỳ giữ lại. – rmaddy

+2

Ngoài ra, bạn đã nhận được ý tưởng rằng các biến __block không được giữ lại ở đâu? ARC sẽ tự động giữ chúng cho bạn, giống như các biến thông thường. –

+2

Trước ARC, các biến __block thực sự không được giữ lại như một cơ chế để tránh các chu kỳ giữ lại. Điều đó đã thay đổi với ARC và được ghi lại trong Ghi chú phát hành chuyển tiếp sang ARC. –

Trả lời

12

__block biến không được giữ lại nếu bạn sử dụng tính năng tham chiếu thủ công. Lý do có thể được tìm thấy ở đây: http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html:

Một cách giải quyết đơn giản này nằm trong thực tế rằng __block biến không được giữ lại. Điều này là do các biến như vậy có thể thay đổi và quản lý bộ nhớ tự động của chúng sẽ yêu cầu mỗi đột biến phải tạo mã quản lý bộ nhớ đằng sau hậu trường. Điều này được xem là quá xâm nhập và khó khăn để có được quyền, đặc biệt là kể từ khi cùng một khối có thể được thực hiện từ nhiều chủ đề cùng một lúc.

và cũng ở đây: http://lists.apple.com/archives/objc-language/2009/Dec/msg00100.html

Không có cách nào để đúng cách và hiệu quả quản lý giữ lại đếm khi tái phân công của giá trị trong biến.

(. Tôi không thể tìm thấy một tài liệu tham khảo "chính thức" trong tài liệu Apple)

Theo tư liệu trong "Transitioning to ARC Release Notes", hành vi này đã thay đổi với ARC:

Trong chế độ hướng dẫn tính tham khảo, __block id x; có hiệu lực không phải là giữ lại x. Ở chế độ ARC, __block id x; mặc định để giữ lại x (chỉ giống như tất cả các giá trị khác). Để có chế độ đếm tham chiếu thủ công hoạt động trong ARC, bạn có thể sử dụng __unsafe_unretained __block id x;. Như tên __unsafe_unretained ngụ ý, tuy nhiên, có một biến số không lưu giữ là nguy hiểm (vì nó có thể dangle) và là do đó không khuyến khích. Hai tùy chọn tốt hơn là sử dụng __weak (nếu bạn không cần hỗ trợ iOS 4 hoặc OS X v10.6) hoặc đặt giá trị __block thành nil để phá vỡ chu kỳ lưu giữ.

+0

Đẹp, có ý nghĩa. Cảm ơn. –

+0

@ darren: Sau khi đọc những tài liệu tham khảo một lần nữa nó có vẻ với tôi rằng tránh giữ chu kỳ là một tác dụng phụ hơn một mục tiêu thiết kế của __block biến. –

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