Delegates in Swift
Bài đăng này đã không được cập nhật trong 7 năm
Delegates là gì?
... trong phát triển phần mềm, chúng là những giải pháp kiến trúc để giải quyết các vấn đề thường gặp trong những ngữ cảnh ( trường hợp) nhất định, nó được nói đến phổ biến nhất là "design patterns". Delegates là "design patterns" cho phép đối tượng gửi "message" đến đối tượng khác khi có một sự kiện đặc biệt xảy ra. Ví dụ khi chúng ta có hai object A và B để thực hiện một hành động. Một khi hành động hoàn tất, object A biết được object B đã thực hiện xong hành động và nó sẽ thực hiện hành động tương ứng tiếp theo từ kết quả của hành động trong object B, điều này có thể giải quyết bằng việc sử dụng delegates. Tốt hơn là xem qua ví dụ để chúng ta dễ thấy hơn Mình sẽ tạo một delegate để truyền dữ liệu giữa hai class. Bạn có thể clone ví dụ tại đây https://github.com/RichardNTran/delegate_iOS Trong này mình sẽ tạo 2 class là IdiotViewController và SmartViewController, Trong SmartViewController sẽ có view cho người dùng chọn yes hoặc no với switch. Sau khi người dùng chọ trả lời cho câu hỏi ở SmartViewController thì kết quả sẽ được update lại cho IdiotViewController và hiển thị trên view. Không có gì phức tạp ở đây, bạn nghĩ cách dễ nhất để có thể update lại kết quả trong view của class IdiotViewController khi người dùng thực hiện go back trở lại màn hình đầu tiên.
Vấn đề ở đây là "switch view" tại màn hình của class SmartViewController và nó không có thể được tham chiếu đến trong class IdiotViewController, vì thế chúng ta cần có một cách để giao tiếp giữa 2 class này- và ở đây delegate sẽ thể hiện được vai trò trong giải quyết vấn đề này.
Đầu tiên mình sẽ tạo một protocal
protocol SmartDelegate: class {
func updateAnswer(_ answer: String)
}
Bước đầu tiên ta tạo một protocal, sau đó chung ta sẽ khởi tạo protocal này như là một thuộc tính trong class SmartViewController, Trong protocal chúng ta có thể tạo ra nhiều functions, dựa trên yêu cầu bạn muốn triển khai sau này. Ở đây mình chỉ tạo một function để nó trả về câu trả lời của người dùng thôi. Tiếp theo tạo thuộc tính delegate ở trong class SmartViewController
weak var delegate: SmartDelegate?
Ở đây bạn phải tạo với weak nhé, để tránh việc tạo nên lỗi retain cycles" nhé - lỗi này làm cho việc thu hồi vùng nhớ không được.( bạn cứ hiểu là A tham chiếu B,,B tham chiếu A mà không cho phép nil thì đẫn đến xoá tên nào cũng không được, nên không thể huỷ các objects kiểu này, làm cho app khi chạy xảy ra tình trangh leak memor)
Sau đó chúng ta sẽ là bước quan trọng, chính là việc truyền data vào function của delegate. Ở đây mình sẽ thực hiện truyền vào delegate câu trả lời của người dùng khi nhấn vào button back trên màn hình
@IBAction func goBack(_ sender: UIBarButtonItem) {
delegate?.updateAnswer(isIdiot.isOn ? "You are Idiot" : "You are not Idiot")
navigationController?.dismiss(animated: true)
}
Tiếp theo, chúng ta sẽ implement SmartDelegate trong class IdiotViewController
class IdiotViewController: UIViewController, SmartDelegate {
...}
Và sẽ define lại function updateAnswer() của delegate. Chính ở đây bạn sẽ giao tiếp được với dữ liệu được đẩy qua từ các object khác. Nhưng tất nhiên chúng ta cần phải làm chính là móc nối liên hệ giữa delegate của class SmartViewController và class IdiotViewController chứ. Như thế thì mới có cái mà để truyền dữ liệu qua về
Mình sẽ món nối nó tạo việc check nếu segue là nhảy đến SmartViewController thì delegate của nó chính là IdiotViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nav = segue.destination as? UINavigationController, let svc = nav.topViewController as? SmartViewController {
svc.delegate = self
}
}
Thế là đã setup xong, giờ chỉ còn việc handle dữ liệu được truyền qua thông qua function updateAnswer thôi
func updateAnswer(_ answer: String) {
answerIdiot.text = answer
}
Chạy và xem kết quả nhé
All rights reserved