Contents
Chào bạn, chúng ta lại tiếp tục seri Lập trình iOS cho mọi người. Bài viết này sẽ nói về Protocol trong Swift. Tìm hiểu về lý thuyết và ứng dụng trong việc coding. Còn nếu bạn chưa biết gì về Swift thì có thể tham khảo bài sau:
Chuẩn bị
- MacOS 10.14.4
- Xcode 11.0
- Swift 5.1
1. Định nghĩa
Protocol dịch ra đầy đủ và đúng nghĩa thì là
giao thức.(Theo Google Translate)
Tới đây thì bạn sẽ ít nhiều đã hiểu về Protocol rồi. Nó xuất hiện khá nhiều trong đời sống hằng ngày của chúng ta mà không hề hay biết. Hơi ngoài lề một chút, giờ chúng ta đi vào chuyện lập trình thôi.
-
Protocol
- Là một kiểu interface
- Mang tính chất trừu tượng
- Khai báo các properties và các methods
- Không định nghĩa chúng
- Implement được vào class/struct/enum
- Implement được vào nhiều chứ không phải một
- Có thể xem như là 1 kiểu dữ liệu
Tới đây cũng là khá đủ rồi, bắt đầu code thôi!
2. Cú pháp
- Từ khoá:
protocol
protocol SomeProtocol {
// protocol definition goes here
}
- Implement
- Struct
struct SomeStructure: FirstProtocol, AnotherProtocol {
// structure definition goes here
}
-
- Class
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
// class definition goes here
}
- Việc Implement thì cũng được xem là một hình thức
đa kế thừađể tăng cường sức mạnh cho class/struct. - Khi class/struct implement một protocol nào đó thì các phương thức và thuộc tính của protocol phải được định nghĩa lại ở class/struct đó
// Protocol
protocol P {
func show()
func add(a: Int, b: Int) -> Int
}
// A class
class A: P {
func show() {
// code here
}
func add(a: Int, b: Int) -> Int {
// code here
return 0
}
}
// B class
class B: P {
func show() {
// code here
}
func add(a: Int, b: Int) -> Int {
// code here
return 0
}
}
3. Property
- Với Protocol thì chúng ta có thể khai báo được các thuộc tính.
- Đây là một điểm mạnh của ngôn ngữ Swift
- Xem ví dụ sau:
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
protocol AnotherProtocol {
static var someTypeProperty: Int { get set }
}
- Ta thấy được một số điều như sau:
- Property có thể là
- Store Property
- Computed Property
- Static hay Non-Static
getchỉ lấy giá trịget setvừa lấy vừa ghi được giá trị
- Property có thể là
- Sử dụng trong struct
- Với biến
fullNamevớiget
- Với biến
protocol FullyNamed {
var fullName: String { get }
}
struct Person: FullyNamed {
var fullName: String
}
let john = Person(fullName: "John Appleseed")
- Sử dụng trong class
- Khi thuộc tính chỉ có
getthì phải định nghĩa lại biến đó rõ ràng hơn thànhreadonly
- Khi thuộc tính chỉ có
class Starship: FullyNamed {
var prefix: String?
var name: String
init(name: String, prefix: String? = nil) {
self.name = name
self.prefix = prefix
}
var fullName: String {
return (prefix != nil ? prefix! + " " : "") + name
}
}
var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
4. Method
- Khai báo phương thức trong protocol tương tự khai báo hàm thông thường, nhưng không cài đặt.
- Việc cài đặt các phương thức này sẽ được class/struct/enum nào áp dụng thực hiện.
- Ngoài ra, protocol cũng cho phép khai báo phương thức mutating để hỗ trợ người dùng thực hiện việc thay đổi giá trị nội tại của class/struct/enum thực thi protocol.
Ví dụ:
protocol SomeProtocol {
static func someTypeMethod()
}
protocol RandomNumberGenerator {
func random() -> Double
}
5. Mutating Method
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 đó.
Phần này thì các bạn nên đọc về Struct và Enum. Vì tụi nó là kiểu tham trị. Còn sau đây là ví dụ đơn giản:
protocol Togglable {
mutating func toggle()
}
enum OnOffSwitch: Togglable {
case off, on
mutating func toggle() {
switch self {
case .off:
self = .on
case .on:
self = .off
}
}
}
var lightSwitch = OnOffSwitch.off
lightSwitch.toggle()
// lightSwitch is now equal to .on
6. Init Method
- Với Class/Struct/Enum thì có hàm khởi tạo
init()để khởi tạo giá trị cho đối tượng đó. - Với Protocol thì cũng có hàm khởi tạo
initnhưng là để các Class/Struct/Enum nào mà implement nó thì phải bắt buộc có hàm khởi tạo này. - Từ khoá sẽ dùng là
required - Ví dụ:
protocol SomeProtocol {
init()
}
class SomeSuperClass {
init() {
// initializer implementation goes here
}
}
class SomeSubClass: SomeSuperClass, SomeProtocol {
// "required" from SomeProtocol conformance; "override" from SomeSuperClass
required override init() {
// initializer implementation goes here
}
}
Giờ thì nhiều bạn sẽ hiểu ra vì sao khi custom view mà tạo sub-class của UIView lại bị bắt cần có mấy cái function
initvới từ khoárequiredở trước nữa.
class MyView:UIView {
init() {}
// Chỗ này bắt buộc nếu ta có viết lại init(), XCode sẽ nhắc và tự thêm như sau
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
7. Class only
Cái tên đã nói lên tất cả rồi.
Khi ta khai báo 1 protocol và kế thừa từ class thì protocol đó sẽ dùng cho mỗi các Class. Còn Struct và Enum thì không dùng được.

- Mục đích to lớn của nó là gì?
- Tạo
delegate&datasource - khai báo với từ khoá
weak - hạn chế leak bộ nhớ
- Tạo
protocol ForClassProtocol: class {
func test()
}
class TestClass: ForClassProtocol {
func test() {}
}
class TestAnotherClass {
weak var delegate: ForClassProtocol?
}
8. Optional Protocol
Có 1 câu hỏi: “Protocol có 100 function được khai báo. Và chúng ta khi implement thì phải định nghĩa lại 100 function đó hay sao? Trong khi nhiều function lại không cần dùng tới.”
Điều này thì hay gặp trong UITableviewDelegate hay UICollectionViewDelegate , bạn chỉ cần khai báo lại một vài function quan trọng. Còn trong khi có nhiều function khác có cũng được hay không có cũng không sao.
Giải quyết điều này, thì người tiền nhiệm của Swift là Objective-C làm việc này rất tốt. Việc của bạn sẽ là:
- Bước 1: thêm từ khoá
@objcđể khai báoprotocolđó xài được với code Objective-C - Bước 2: Thêm từ khoá
optionaltrước function nào mà bạn mong muốn là không cần định nghĩa lại thì vẫn được. - Ví dụ:
@objc protocol P {
func show()
func add(a: Int, b: Int) -> Int
@objc optional func sum(array: [Int]) -> Int
}
class A: P {
func show() {
// code here
}
func add(a: Int, b: Int) -> Int {
// code here
return 0
}
}
class B: P {
func show() {
// code here
}
func add(a: Int, b: Int) -> Int {
// code here
return 0
}
func sum(array: [Int]) -> Int {
return 0
}
}
9. Extension
Để sử dụng Protocol một cách chuyên nghiệp hơn thì lời khuyên của mình dành cho bạn là: “nên tạo extension cho class/struct/enum đó và implement protocol.”
Vì 1 class có thểm implement rất nhiều protocol và chúng nó có thể trùng tên với nhau hoặc bạn sẽ không phân biệt được function nào của protocol nào.
@objc protocol P {
func show()
func add(a: Int, b: Int) -> Int
@objc optional func sum(array: [Int]) -> Int
}
class C {
var a: Int
var b: Int
var result: Int = 0
init(a: Int, b: Int) {
self.a = a
self.b = b
}
}
extension C: P {
func show() {
print("result: \(result)")
}
func add(a: Int, b: Int) -> Int {
return a + b
}
}
Tới đây thì sang phần kết được rồi. Rất nhiều thứ đã được học.
Tạm kết
- Tìm hiểu về Protocol
- Khai báo và sử dụng Protocol
- Các tính chất, đặc trưng của thuộc tính và phương thức trong Protocol
- Các lưu ý về khởi tạo và class
- Cách implement Protocol hiệu quả với Extension
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Non-Tech Builders 2026: Bùng Nổ Của Prototypes, Không Phải Revolution
- Multi-Layer Prompt Architecture – Chìa khóa Xây dựng Hệ thống AI Phức tạp
- Khi “Prompt Template” Trở Thành Chiếc Hộp Pandora
- Vòng Lặp Ảo Giác
- Giàn Giáo Nhận Thức (Cognitive Scaffold) trong Prompt Engineering
- Bản Thể Học (Ontology) trong Prompt Engineering
- Hướng Dẫn Vibe Coding với Gemini CLI
- Prompt Bản Thể Học (Ontological Prompt) và Kiến Trúc Nhận Thức (Cognitive Architecture Prompt) trong AI
- Prompt for Coding – Code Translation Nâng Cao & Đối Phó Rủi Ro và Đảm Bảo Chất Lượng
- Tại sao cần các Chiến Lược Quản Lý Ngữ Cảnh khi tương tác với LLMs thông qua góc nhìn AI API
You may also like:
Archives
- December 2025 (1)
- October 2025 (1)
- September 2025 (4)
- August 2025 (5)
- July 2025 (10)
- June 2025 (1)
- May 2025 (2)
- April 2025 (1)
- March 2025 (8)
- January 2025 (7)
- December 2024 (4)
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)






