Method swizzling là gì nên sử dụng khi nào năm 2024
Trong Swift, chúng ta có khá nhiều cách để truyền dữ liệu qua lại giữa các đối tượng. Bài viết này mình muốn chia sẻ với các bạn về một số kỹ thuật phổ biến và ưu nhược điểm của nó. Bài viết này mình sẽ đề cập đến 3 cách phổ biến đó là Delegation, Closure và NotificationCenter Observation Bài toánMàn hình của mình cần làm có một UITableView, trong UITableView này chứa các UITableViewCell các cell thì có chứa 2 UIButton Dark và Light. Việc của mình phải làm là mỗi khi người dùng tương tác với button ở trong cell thì UIViewController sẽ bắt được sự kiện và hiển thị lên màn hình thông tin cell và hành động mà người dùng vừa tương tác. Các bạn tải về project bắt đầu này để tiện hơn trong quá trình thực hành nhé: DelegationDelegation là một design pattern cho phép đối tượng gửi thông điệp(data, message …) đến đối tượng khác khi có một sự kiện xảy ra. Ví dụ ta có 2 đối tượng A và B, trên B thực hiện hành động gửi thông điệp sang A để A thực hiện hành động dựa trên kết quả hành động trên B. Do chúng bài toán của chúng ta cần bắt hành động của người dùng khi họ action lên các button trên cell vì thế trong trường hợp này trong UITableViewCell chúng ta cần tạo protocol cho MyTableViewCell.swift cụ thể như sau:
Ở đây mình tạo ra protocol định nghĩa các action trên cell. Khi người dùng bấm vào button Dark nó sẽ call protocol này tương tự với Button Light. Tiếp đến chúng ta tạo thêm 2 variables để lưu delegate và indexPath:
Đối với delegate chúng ta cần khai báo weak để tránh tham chiếu strong dẫn đến Retain cycle, không giải phóng được các object này vì nó đang tham chiếu tới nhau. Tiếp đến chúng ta cần gọi các protocol tương ứng khi người dùng tương tác lên các button trên cell:
Vậy là chúng ta đã setup protocol cho MyTableViewCell.swift giờ tất cả những UIViewController nào sử dụng cell này đều có thể conform protocol của nó để bắt được event khi người dùng tương tác lên các button cell. Giờ chúng ta quay lại file ViewController.swift kéo xuống hàm cellForRowAt indexPath của tableview và update như sau:
Chúng ta gán lại giá trị indexPath cho các cell. Và set delegate cho Cell là self(viewController hiện tại) Lúc này XCode sẽ báo lỗi Cannot assign value of type ‘ViewController’ to type ‘ActionOnCell?’ vì chúng ta chưa conform protocol ActionOnCell trên ViewController. Vì vậy chúng ta sẽ tạo 1 extension của ViewController và conform ActionOnCell
Khi người dùng tap vào button trên cell nó sẽ call protocol tương ứng và trả dữ liệu về cho viewController vì vậy bạn có thể sử dụng dữ liệu mà bạn muốn để update dữ liệu lên màn hình. Các bạn Build project sẽ nhận được kết quả như sau: NotificationCenter observationLà một cơ chế gửi thông báo cho phép truyền phát thông tin đến các đối tượng đã đăng ký quan sát notification đó. Chúng ta sẽ dựa trên 2 cơ chế post và observer của NotificationCenter để gửi và nhận dữ liệu giữa các đối tượng. Đối với notification thì chúng ta có thể sử dụng gửi thông tin từ một đối tượng đến nhiều đối tượng khác đã đăng ký theo dõi notification đó. Cụ thể trong bài toán này chúng ta sẽ làm như sau: Tạo 2 notification Name đinh nghĩa việc người dùng bấm vào Button Dark và Light:
Mở file MyTableViewCell.swift thực hiện việc phát(post) thông báo tại 2 event của 2 button trên cell cụ thể như dưới đây:
Nhiệm vụ của 2 hàm này là để khi nào người dùng bấm vào nut Dark hoặc Light thì NotificationCenter sẽ gửi đi một notification, những đối tượng nào đang lắng nghe các notification name đó sẽ nhận được thông điệp. Vì vậy chúng ta cần add observer cho ViewController.swift để nó nhận được thông tin khi người dùng tương tác lên các button trên cell. Chúng ta sẽ làm như sau:
Chúng ta cần đăng ký theo dõi notification ở viewWillApper và Remove theo dõi notification khi viewWillDisappear vì nếu chúng ta không remove view controller sẽ luôn nhận được thông báo khi mà nó còn trong view hierarchy dẫn đến những lỗi không mong muốn.
Giờ build ứng dụng và các bạn sẽ nhận được kết quả tương tự như phần delegation ClosureNếu các bạn muốn tìm hiểu rõ hơn về Closure hãy đọc tài liệu tham khảo của Apple: https://docs.swift.org/swift-book/LanguageGuide/Closures.html Ý tưởng ở đây chúng ta sẽ tạo 1 closure callback có 2 tham số là action type và dữ liệu truyền lại là index path. Mở file MyTableViewCell.swift và thêm 1 enum định nghĩa các kiểu action trên cell
Tạo closure cho MyTableViewCell
0 Gọi closure khi người dùng bấm vào các nút trên cell
1 Tiếp đến để nhận được event khi người dùng bấm vào các button chúng ta cần gán giá trị cho closure ở nơi mà bạn muốn. Cụ thể trong trường hợp này là ViewController.swift
2 Giờ run ứng dụng chúng ta sẽ được kết quả như 2 cách trên. Đánh giá
Tổng kếtMình hi vọng bài viết giúp cho các bạn có thể lựa chọn các cách truyền dữ liệu phù hợp với bài toán của mình. Chúc các bạn thành công! |