xem xét như thế nào ARC làm việc với biến - mỗi biến tài liệu tham khảo có một chế độ (ngầm hoặc rõ ràng): mạnh, yếu vv Chế độ này cho phép của ARC biết làm thế nào để xử lý đọc và viết để biến; ví dụ. cho việc đọc biến số mạnh mẽ không yêu cầu thêm hành động nào trong khi viết yêu cầu giải phóng tham chiếu hiện tại trong biến trước khi thay thế bằng biến mới. ARC cần biết chế độ của bất kỳ biến nào để hoạt động.
Bây giờ, hãy xem xét các biến tự được chuyển bởi tham chiếu, ví dụ: cho bạn execute
bạn sẽ có một cuộc gọi dọc theo dòng:
NSError *myError = nil;
...
[someObject execute:&myError]; // pass the variable itself by reference, not the variables value
và cơ thể của execute
sẽ chứa một bài tập dọc theo dòng:
- (void)execute:(NSError * __autoreleasing *)error
{
...
if (error != NULL)
*error = [NSError ...]; // assign indirectly via the reference to a variable
...
}
Bây giờ cho rằng nhiệm vụ gián tiếp ARC cần biết chế độ của biến được tham chiếu để nó biết cách đọc và viết. Đó là những gì các __autoreleasing
là trong tuyên bố, nó nói với ARC rằng nó đã được thông qua một tham chiếu đến một biến có chế độ là autoreleasing và điều đó cho ARC biết cách đọc và ghi nội dung của biến. Loại bỏ các __autoreleasing
và một chế độ mặc định sẽ được giả định, và trong trường hợp này tôi muốn đề nghị rõ ràng là chắc chắn tốt.
Chế độ tự động tự động trả tiền có nghĩa là biến chứa tham chiếu không thuộc sở hữu, lần đọc giữ lại nếu cần và viết chỉ có thể viết. Nó được sử dụng chủ yếu cho các biến được truyền qua tham chiếu.
Bạn có thể nhận thấy rằng trong ví dụ trên biến myError
có chế độ mạnh (ngầm) nhưng nó được thông qua tham khảo như autoreleasing - trình biên dịch xử lý này sẽ tự động bằng cách giới thiệu một biến autoreleasing tạm thời, sao chép không giữ lại tham chiếu hiện tại trong myError
vào đó và chuyển tạm thời theo tham chiếu làm đối số đến execute:
. Sau khi cuộc gọi trả về trình biên dịch thực hiện một nhiệm vụ bình thường từ tạm thời đến myError
, kết quả trong bất kỳ tài liệu tham khảo cũ được phát hành và một trong những trả lại giữ lại.
Để biết thêm chi tiết, xem Apple's Transitioning to ARC Release Notes
followup để Comments
Q: Liệu __autoreleasing
ngầm thiết lập?
A: Vâng Apple's tài liệu không cụ thể, nhưng Clang documentation nói rằng nó là ẩn đối với các tham số gián tiếp. Như trên, tôi khuyên bạn nên rõ ràng, rõ ràng là một Good Thing ™.
Q: Vị trí có quan trọng không?
A: Có, và không ... Đây là bản khai C, nội dung câu đố ("Tuyên bố sau đây ...") là gì. Vòng loại phải nằm giữa hai dấu hoa thị vì nó là con trỏ tự động đến con trỏ tự động (biến kiểu) đối với một đối tượng, nhưng Apple trình biên dịch là "tha thứ" mà không được cụ thể về những gì nó tha thứ. Chơi nó an toàn, đặt nó vào đúng nơi.
Q: Nếu bạn không kiểm tra error
là NULL
trước khi thực hiện chuyển nhượng gián tiếp?
A: Tất nhiên, bạn nên ở đâu đó trước khi bạn thực hiện việc chuyển hướng. Mã được hiển thị chỉ là một đường viền và các chi tiết như vậy được elided và bao phủ bởi các của ...
. Tuy nhiên vì nó đã được nâng lên một vài lần trong những năm qua có lẽ tôi đã bỏ qua quá nhiều, một số if
phù hợp đã được thêm vào.
Vì vậy, '__autoreleasing' được đặt ngầm định nếu tôi không đặt rõ ràng? Ngoài ra, vị trí của vấn đề '__autoreleasing' (trước, bên trong hoặc sau dấu sao)? – chinabuffet
@chinabuffet - Xem followup trong câu trả lời – CRD
@CRD câu trả lời hay. Nhưng bạn có thể muốn chỉ ra rằng bạn nên kiểm tra nếu 'error' là' NULL' trước khi gán cho '* error'. Nếu không, phương pháp của bạn có thể làm hỏng ứng dụng của bạn vì '[foo execute: NULL]' là một thực thi hoàn toàn hợp lệ và cách để nói "Tôi không quan tâm đến lỗi". – Joel