Weak attribute và ứng dụng thực tế trong iOS
1. Vấn đề về quản lý bộ nhớ Như đã nói ở bài trước. Những device của Apple thường có RAM dung lượng không được cao, khi một ứng dụng đang chạy mà chiếm dụng quá nhiều bộ nhớ, hoặc không kiểm soát được vòng đời của tất cả các đội tượng lưu trữ dữ liệu của ứng dụng đó thì rất có thể sẽ dẫn đến ...
1. Vấn đề về quản lý bộ nhớ Như đã nói ở bài trước. Những device của Apple thường có RAM dung lượng không được cao, khi một ứng dụng đang chạy mà chiếm dụng quá nhiều bộ nhớ, hoặc không kiểm soát được vòng đời của tất cả các đội tượng lưu trữ dữ liệu của ứng dụng đó thì rất có thể sẽ dẫn đến crash ứng dụng đang chạy hoặc hệ thống tự động stop các ứng dụng khác. Vì thế việc quản lý bộ nhớ trong iOS luôn được quan tâm và đặt lên hàng đầu trong quá trình phát triển phần mềm. Để cải thiện việc quản lý bộ nhớ đối tượng (property) này, ở version iOS 5, Apple đã giới thiệu cho chúng ta thêm một attribute là weak.
2. weak là gì? Một property có attribute weak thì property đó có thể tham chiếu đến một đối tượng khác mà không sở hữu đối tượng đó. Khi đối tượng đó được set về nil thì property này cũng tự động có giá trị nil Mẫu khai báo một property thông dụng có attribute weak theo Objective - C:
@property (nonatomic, weak) NSString *string; //Objective - C weak var string: String? //Swift
weak được dùng để tránh strong reference cycles
3. Các ứng dụng thực tế a. Delegate properties Ví dụ 1:
//swift @objc protocol Delegate { func funcA() } class A { weak var delegate: Delegate? } class ViewController: Delegate { var a: A? func configure() { a = A() a.delegate = self } }
Nếu biến delegate là kiểu strong, thì retaincount của view controller đó sẽ được tăng thêm 1 nữa. Khi view controller bị dealloc thì nó chỉ giảm retaincount đi 1, nếu trước đó không set nil cho a thì retaincount vẫn lớn hơn 0. nếu vậy, sẽ gây nên tình trạng rò rỉ vùng nhớ cho view controller vì ta không thể tác động/ kiểm soát nó được nữa
b. Block/Closure properties tương tự delagate ví dụ 1:
class A { weak var closure: (text: String)? } class ViewController: Delegate { var a: A? func configure() { a = A() a.closure = {(text: String) in } } }
ví dụ 2:
class A { var closure: (text: String)? } class ViewController: Delegate { var a: A? func configure() { a = A() a.closure = {[weak self] (text: String) in } } }
c. Những subview/control của main view của những view controller ví dụ:
//swift @IBOutlet weak var tableView: UITableView!
Ở đây ta khai báo kiểu weak bởi vì biến tableView đã được strong held bởi main view rồi, nếu ta khai báo là strong thì nó sẽ tăng thêm retaincount của UITableView component trong file .xib đó lên 1 đơn vị nữa. Khi view controller bị dealloc thì cái table view trong file xib đó vẫn không bị dealloc vì retaincount của nó vẫn > 0.
Vậy, weak sinh ra là để giải quyết vấn đề strong reference cyles , đó là tình huống mà 2 đối tượng strong reference với nhau, và chúng sẽ không bao giờ bị destroyed bởi ARC.
Cảm ơn mọi người đã đọc bài viết này.
Rất trân trọng.