20

Giả sử đoạn mã sau dưới ARC,Trong ARC, các khối có được tự động sao chép khi được gán trực tiếp cho một ivar không?

typedef void (^MyResponseHandler) (NSError *error); 
@interface MyClass : NSObject 
{ 
    MyResponseHandler _ivarResponseHandler; 
} 

- (void)myMethod:(MyResponseHandler)responseHandler 
{ 
    _ivarResponseHandler = responseHandler; 
    ... 
} 

Câu hỏi: Sản phẩm block tự động sao chép vào đống khi gán cho Ivar?

My previous question ngụ ý rằng nó được sao chép khi được gán thông qua @property. Nhưng, hôm nay tôi đã sử dụng mã ở trên và đã nhận được EXC_BAD_ACCESS đã được sửa bằng cách thay đổi thành

_ivarResponseHandler = [responseHandler copy].

Trả lời

4

Vấn đề và giải pháp của bạn cho thấy câu trả lời của tôi cho câu hỏi khác của bạn có thể là sai. Tôi dựa trên đoạn cuối của phần 7,5 của the clang Objective-C Automatic Reference Counting documentation:

Ngoại trừ vẫn nắm quyền thực hiện như một phần của khởi tạo một biến tham số __strong hay đọc một biến __weak, bất cứ khi nào những ngữ nghĩa kêu gọi duy trì một giá trị của block loại con trỏ, nó có tác dụng của một Block_copy. Trình tối ưu hóa có thể xóa các bản sao như vậy khi thấy kết quả chỉ được sử dụng làm đối số cho cuộc gọi.

tôi mất “những ngữ nghĩa” có nghĩa là toàn bộ tài liệu, nhưng nếu “những ngữ nghĩa” để đề cập đến chỉ mục 7.5, sau đó ARC chỉ chèn một Block_copy cho một khối được chụp bởi một khối.

+0

Tôi đồng ý không rõ "những ngữ nghĩa" này đề cập đến – sbooth

+0

+1, từ ngữ phần là vô cùng khó hiểu. – orip

+3

Tôi đã nói chuyện với kỹ sư của Apple đã viết phần này. Ông nói "những ngữ nghĩa" đề cập đến toàn bộ tài liệu. Do đó, 'Block_copy' sẽ được chèn tự động. Dường như đây có thể là lỗi sớm với các khối sau đó đã được sửa. – bearMountain

10

Chỉnh sửa: Câu trả lời trước của tôi có thể là sai.

Một số đoạn trích chọn từ ARC docs nói:

3. Retainable đối tượng con trỏ

Một con trỏ đối tượng retainable (hoặc con trỏ retainable) là một giá trị của một loại con trỏ đối tượng retainable (loại retainable). Có ba loại của các loại con trỏ đối tượng retainable:

  • khối con trỏ (hình thành bằng cách áp dụng các dấu mũ (^) declarator sigil cho một loại chức năng)

4,2. Semantics

Chuyển nhượng xảy ra khi đánh giá toán tử gán. Các ngữ nghĩa khác nhau tùy theo trình độ:

  • Đối với các đối tượng _strong, điểm đánh dấu mới đầu tiên được giữ lại; thứ hai, các lvalue được nạp với ngữ nghĩa nguyên thủy; thứ ba, pointee mới được lưu vào lvalue với ngữ nghĩa nguyên thủy; và cuối cùng, con trỏ cũ được phát hành. Điều này không được thực hiện một cách nguyên tử; đồng bộ hóa bên ngoài phải được sử dụng để thực hiện điều này an toàn khi đối mặt với các tải và cửa hàng đồng thời.

4.4.1.Đối tượng

Nếu đối tượng được khai báo với loại chủ sở hữu đối tượng có thể lưu lại nhưng không có vòng loại quyền sở hữu rõ ràng, loại của nó được điều chỉnh hoàn toàn để có chứng chỉ __strong.

7.5. Các khối

Ngoại trừ việc giữ lại được thực hiện như là một phần của việc khởi tạo biến thông số __strong hoặc đọc biến __weak, bất cứ khi nào các ngữ nghĩa này gọi giữ lại giá trị kiểu con trỏ khối, nó có tác dụng của Block_copy. Trình tối ưu hóa có thể xóa các bản sao như vậy khi thấy kết quả chỉ được sử dụng làm đối số cho cuộc gọi.

Vì vậy, tôi nghĩ câu trả lời là có thể là, tùy thuộc vào trình tối ưu hóa.

+0

Bạn có biết rằng tôi yêu cầu tham chiếu đến môi trường được tính tham chiếu tự động không? Có vẻ như ví dụ foo/bar của bạn sẽ không phải là một vấn đề trong ARC ...? – bearMountain

+0

Vâng, xin lỗi. Câu trả lời của bạn, hoặc tài liệu hướng dẫn táo cung cấp không nói gì về việc liệu ARC có tự động di chuyển một khối tới vùng heap khi được gán cho một biến cá thể hay không. Có vẻ như câu trả lời cho câu hỏi này sẽ phải đến từ tài liệu đếm tài liệu tham khảo tự động [clang Objective-C] (http://clang.llvm.org/docs/AutomaticReferenceCounting.html#misc.blocks). – bearMountain

+0

@bearMountain Bạn nói đúng, tôi đã cố gắng sửa chữa câu trả lời của tôi. – sbooth

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