Cả hai weak
và các unowned
tham chiếu đều không tạo ra sự strong
giữ đối tượng được giới thiệu (hay còn gọi là chúng không tăng số lần giữ lại để ngăn ARC giải phóng đối tượng được giới thiệu).
Nhưng tại sao hai từ khóa? Sự khác biệt này có liên quan đến thực tế là Optional
các loại được tích hợp sẵn trong ngôn ngữ Swift. Câu chuyện dài về chúng: các loại tùy chọn cung cấp sự an toàn cho bộ nhớ (điều này hoạt động rất tốt với các quy tắc xây dựng của Swift - vốn rất nghiêm ngặt để cung cấp lợi ích này).
Một weak
tài liệu tham khảo cho phép các khả năng của nó để trở thành nil
(điều này xảy ra tự động khi đối tượng tham chiếu được deallocated), do đó các loại tài sản của bạn phải là tùy chọn - vì vậy bạn, như một lập trình viên, có nghĩa vụ để kiểm tra nó trước khi bạn sử dụng nó (về cơ bản trình biên dịch buộc bạn, càng nhiều càng tốt, để viết mã an toàn).
Một unowned
tài liệu tham khảo cho rằng nó sẽ không bao giờ trở thành nil
trong suốt cuộc đời của nó. Một tham chiếu không được đặt tên phải được đặt trong quá trình khởi tạo - điều này có nghĩa là tham chiếu đó sẽ được xác định là loại không tùy chọn có thể được sử dụng một cách an toàn mà không cần kiểm tra. Nếu bằng cách nào đó, đối tượng được đề cập bị hủy bỏ, thì ứng dụng sẽ bị sập khi tham chiếu không có tên sẽ được sử dụng.
Từ các tài liệu của Apple :
Sử dụng một tham chiếu yếu bất cứ khi nào nó có giá trị để tham chiếu đó trở thành con số không tại một thời điểm nào đó trong suốt vòng đời của nó. Ngược lại, sử dụng một tham chiếu chưa được đặt tên khi bạn biết rằng tham chiếu đó sẽ không bao giờ là không khi nó đã được đặt trong quá trình khởi tạo.
Trong các tài liệu, có một số ví dụ thảo luận về các chu kỳ giữ lại và cách phá vỡ chúng. Tất cả những ví dụ này được trích xuất từ các tài liệu .
Ví dụ về weak
từ khóa:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
}
Và bây giờ, đối với một số nghệ thuật ASCII (bạn nên đi xem các tài liệu - chúng có sơ đồ đẹp):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
Các Person
và Apartment
ví dụ chương trình một tình huống mà hai tài sản, cả hai đều được cho phép trở thành con số không, có khả năng gây ra một chu kỳ tài liệu tham khảo mạnh mẽ. Kịch bản này được giải quyết tốt nhất với một tài liệu tham khảo yếu. Cả hai thực thể có thể tồn tại mà không có sự phụ thuộc chặt chẽ vào nhau.
Ví dụ về unowned
từ khóa:
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}
Trong ví dụ này, a Customer
có thể có hoặc không có a CreditCard
, nhưng a CreditCard
sẽ luôn được liên kết với a Customer
. Để thể hiện điều này, Customer
lớp có một thuộc tính tùy chọn card
, nhưng CreditCard
lớp có thuộc tính không tùy chọn (và không có tên) customer
.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
Các Customer
và CreditCard
ví dụ chương trình một tình huống mà một tài sản được phép trở thành con số không và một tài sản đó không thể bằng không có khả năng gây ra một chu kỳ tài liệu tham khảo mạnh mẽ. Kịch bản này được giải quyết tốt nhất với một tài liệu tham khảo chưa được đăng.
Lưu ý từ Apple:
Tham chiếu yếu phải được khai báo là biến, để chỉ ra rằng giá trị của chúng có thể thay đổi khi chạy. Một tham chiếu yếu không thể được khai báo là hằng số.
Ngoài ra còn có một kịch bản thứ ba khi cả hai thuộc tính phải luôn có một giá trị và không thuộc tính nào sẽ không có giá trị nào khi quá trình khởi tạo hoàn tất.
Và cũng có những kịch bản giữ chu kỳ cổ điển cần tránh khi làm việc với các bao đóng.
Đối với điều này, tôi khuyến khích bạn truy cập tài liệu của Apple hoặc đọc sách .