13/09/2018, 08:51

Protocol trong Swift

1. Giới thiệu Protocol Khi nói đến Protocol nghĩa là ta đang nói đến 1 cái gì đó trừu tượng. Vậy trừu tượng là sao ? Thông thường ta sẽ biết được “Con mèo kêu meo meo. Con chó kêu gâu gâu. Con vịt kêu cạp cạp” nhưng ta lại không thể dám chắc rằng “Vật nuôi thì kêu ...

1. Giới thiệu Protocol

Khi nói đến Protocol nghĩa là ta đang nói đến 1 cái gì đó trừu tượng. Vậy trừu tượng là sao ? Thông thường ta sẽ biết được “Con mèo kêu meo meo. Con chó kêu gâu gâu. Con vịt kêu cạp cạp” nhưng ta lại không thể dám chắc rằng “Vật nuôi thì kêu thế nào hoặc gia giầm thì kêu ra sao”. Vì thế ta gọi nó là trừu tượng, mặc dù ta luôn biết là vật nuôi hay gia cầm nào cũng có thể kêu được.

Trong thế giới lập trình cũng vậy, người ta quy các vấn đề / hành vi / thuộc tính mà được sử dụng trong rất nhiều các đối tượng khác nhau lập thành protocol. Để minh họa mình sẽ tạo một protocol CanMakeSound (có thể kêu được) và cách sử dụng protocol này.

Tới đây ta biết được protocol có thể được sử dụng bởi class, struct và cả enum (thật bá đạo). Khi protocol được adopted ở đâu thì nơi đó (class/struct/enum) phải định nghĩa và viết chi tiết cho tất cả các methods mà protocol đó có. Tới đây chúng ta thấy protocol có vẻ giống với khái niệm interface trong các ngôn ngữ hướng đối tượng khác như Java, C#, … Trong Swift protocol không chỉ có method mà còn có property nữa (bá đạo tập 2)

2. Mutating methods trong protocol

Mutabling method trong protocol nghĩa là cho phép method đó thay đổi thuộc tính nội tại (instance property) của Struct hoặc Enum mà adopt protocol đó. Để minh họa mình sẽ edit lại enum DogStatus ở trên một chút:

3. Method khởi tạo (init) trong protocol

Trong Swift ta có các method đặc biệt dùng để khởi tạo Class, Struct và Enum cũng không ngoại lệ (bá đạo tập 3). Protocol trong Swift cũng có thể chứa các method init nhằm đảm bảo rằng ai mà adopt nó thì phải viết chi tiết cho hàm khởi tạo. Thế nhưng riêng với class thì có hơi khác 1 tí:

Đối với class, ta cần từ khóa required trước khai báo hàm khởi tạo. Mình sẽ làm 1 bài khác chi tiết hơn về các method khởi tạo.

Thực tế ta sẽ thường gặp từ khóa này khi subclass một UIView và viết lại hàm init cho nó. Trình biên dịch bắt ta phải required method. Đại loại là như sau:

Lý do là tại vì bản thân UIView có adopt 1 protocol tên là: NSCoding và trong protocol này có hàm public init?(coder aDecoder: NSCoder)

4. Protocol for class-only

Nói nhanh gọn là protocol class-only nghĩa là chỉ xài được cho class mà thôi. Mặc định Protocol là kiểu giá trị (value type), và ta có thể biến nó thành kiểu tham chiếu bằng cách:

Protocol:class còn được sử dụng vào mục đích tạo delegate. Nếu ta dùng 1 object (class instance) để làm delegate thì chúng ta khai với từ khóa weak (để chống retain cycle dẫn tới leak memory). Nhưng nếu ta gán 1 giá trị (enum/struct) và biến weak này thì sẽ bị báo lỗi do biến weak chỉ đi với kiểu tham chiếu (class) thôi.

5. Optional Protocol Requirements

Tới đây chúng ta đã biết 1 nguyên tắc cơ bản khi dùng protocol là trong đó có bao nhiêu method thì mình phải viết lại bấy nhiêu method khi mình adopt nó. Như vậy thì lỡ mà protocol đó có quá nhiều method thì sao trời, ngồi viết hết chắc cắn lưỡi quá @@.

Apple cung cấp cho ta 1 giải pháp là dùng thêm từ khóa @objc, từ khóa này chỉ ra rằng protocol này có thể dùng được với code Objective C, nghe chả liên quan gì cả nhưng thật sự nó như vậy, bất kể ta có dùng code Objective C trong project hay không. Từ khóa này cũng sẽ làm cho protocol trở thành for class-only

Vậy là thực tế Protocol trong Swift (thuần) sẽ không có khái niệm optional method … nghĩa là nếu ta dùng Protocol cho 1 struct/enum thì có bao nhiêu method thì viết bấy nhiêu lại thôi.

Techtalk via IDE Academy

0