Trình biên dịch LLVM 3.0 giới thiệu bốn vòng loại quyền sở hữu mới: __strong
, __autoreleasing
, __unsafe_unretained
và __weak
. Ba số đầu tiên khả dụng ngay cả bên ngoài ARC, theo số the specification.
Như Joshua cho biết, theo mặc định, tất cả các con trỏ được ngụ ý là __strong
trong ARC. Điều này có nghĩa là khi một đối tượng được gán cho con trỏ đó, nó được giữ lại miễn là con trỏ đó đề cập đến nó. Điều này là tốt cho hầu hết mọi thứ, nhưng nó mở ra khả năng giữ lại chu kỳ, như tôi mô tả trong câu trả lời của tôi here. Ví dụ, nếu bạn có một đối tượng có chứa một đối tượng khác như một biến cá thể, nhưng đối tượng thứ hai đó có một liên kết mạnh trở lại đối tượng đầu tiên làm đại biểu của nó, hai đối tượng sẽ không bao giờ được giải phóng.
Đó là vì lý do này tồn tại vòng loại __unsafe_unretained
và __weak
. Cách sử dụng phổ biến nhất của họ là dành cho đại biểu, nơi bạn muốn xác định thuộc tính cho đại biểu đó với thuộc tính weak
hoặc unsafe_unretained
(assign
là hiệu quả unsafe_unretained
) và sau đó so khớp nó bằng cách đánh dấu biến mẫu tương ứng với __weak
hoặc __unsafe_unretained
. Điều này có nghĩa là biến cá thể đại biểu vẫn sẽ trỏ ngược lại đối tượng đầu tiên, nhưng nó sẽ không khiến đối tượng đó được giữ lại, do đó phá vỡ chu trình lưu giữ và cho phép cả hai đối tượng được giải phóng.
Ngoài các đại biểu, điều này rất hữu ích để phá vỡ bất kỳ chu kỳ giữ chân nào khác có thể hình thành trong mã của bạn. Một cách hữu ích, công cụ Rò rỉ giờ đây bao gồm chế độ xem Chu kỳ, cho thấy các chu kỳ lưu giữ mà nó phát hiện trong ứng dụng của bạn theo cách đồ họa.
Cả hai __unsafe_unretained
và __weak
ngăn việc lưu giữ các đối tượng, nhưng theo những cách hơi khác nhau. Đối với __weak
, con trỏ đến một đối tượng sẽ chuyển đổi thành nil
trên deallocation của đối tượng nó trỏ đến, đó là hành vi rất an toàn.Như tên gọi của nó, __unsafe_unretained
sẽ tiếp tục trỏ đến bộ nhớ có đối tượng, ngay cả sau khi nó được deallocated. Điều này có thể dẫn đến sự cố do truy cập vào đối tượng deallocated đó.
Tại sao bạn sẽ sử dụng __unsafe_unretained
sau đó? Thật không may, __weak
chỉ được hỗ trợ cho iOS 5.0 và Lion làm mục tiêu triển khai. Nếu bạn muốn nhắm mục tiêu trở lại iOS 4.0 và Snow Leopard, bạn phải sử dụng loại vòng loại __unsafe_unretained
hoặc sử dụng thứ gì đó giống như của Mike Ash MAZeroingWeakRef.
Và tất nhiên '__unsafe_unretained' có thể là hữu ích cho việc xác định các mảng C của 'NSString' hằng số và tương tự, ví dụ 'NSString __unsafe_unretained * myStrings = {@" Foo ", @" Bar ", @" Baz ", nil};' – jlehr
Cảm ơn câu trả lời tuyệt vời. khi tôi sử dụng __unsafe_unretained sẽ iOS tham khảo nó như _weak nếu hệ điều hành thiết bị là 5? hoặc nó được đặt ở thời gian biên dịch trên xCode? – shannoga
@shannoga - Không, bạn phải chỉ định bằng tay '__weak' làm bộ định tính để sử dụng những loại con trỏ đó. Bạn vẫn có thể sử dụng '__unsafe_unretained' với mục tiêu thuần túy là 5.0 và nó sẽ không hoạt động như' __weak'. Nếu bạn muốn một cái gì đó sẽ chuyển đổi giữa hai chế độ tùy thuộc vào việc mục tiêu của bạn có hỗ trợ nó hay không, bạn có thể sử dụng một định nghĩa trình biên dịch cụ thể như tôi đề xuất ở đây: http://stackoverflow.com/a/8594878/19679 –