Skip to content
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Fx Studio
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Written by chuotfx on October 24, 2019

Protocol trong 10 phút

iOS & Swift

Contents

  • Chuẩn bị
  • 1. Định nghĩa
      • Protocol
  • 2. Cú pháp
  • 3. Property
  • 4. Method
  • 5. Mutating Method
  • 6. Init Method
  • 7. Class only
  • 8. Optional Protocol
  • 9. Extension
  • Tạm kết

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:

  • Basic Swift trong 10 phút

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
    • get chỉ lấy giá trị
    • get set vừa lấy vừa ghi được giá trị
  • Sử dụng trong struct
    • Với biến fullName với get
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ó get thì phải định nghĩa lại biến đó rõ ràng hơn thành readonly
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 init như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 init vớ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ớ
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áo protocol đó xài được với code Objective-C
  • Bước 2: Thêm từ khoá optional trướ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
FacebookTweetPinYummlyLinkedInPrintEmailShares11

Related Posts:

  • Nimble
    Nimble trong 10 phút
  • Semaphore
    Dispatch Semaphore trong 10 phút
  • feature_bg_blog_005
    Phù thủy phiên dịch ý tưởng
  • Quick
    Quick trong 10 phút
Tags: basic ios tutorial, iOS, protocol
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

Your email address will not be published. Required fields are marked *

Donate – Buy me a coffee!

Fan page

Fx Studio

Tags

Actor Advanced Swift AI api AppDistribution autolayout basic ios tutorial blog ci/cd closure collectionview combine concurrency crashlytics dart dart basic dart tour Declarative delegate deploy design pattern fabric fastlane firebase flavor flutter GCD gradients iOS MVVM optional Prompt engineering protocol Python rxswift safearea Swift Swift 5.5 SwiftData SwiftUI SwiftUI Notes tableview testing TravisCI unittest

Recent Posts

  • Role-playing vs. Persona-based Prompting
  • [Swift 6.2] Raw Identifiers – Đặt tên hàm có dấu cách, tại sao không?
  • Vibe Coding là gì?
  • Cách Đọc Sách Lập Trình Nhanh và Hiệu Quả Bằng GEN AI
  • Nỗ Lực – Hành Trình Kiến Tạo Ý Nghĩa Cuộc Sống
  • Ai Sẽ Là Người Fix Bug Khi AI Thống Trị Lập Trình?
  • Thời Đại Của “Dev Tay To” Đã Qua Chưa?
  • Prompt Engineering – Con Đường Để Trở Thành Một Nghề Nghiệp
  • Vấn đề Ảo Giác (hallucination) khi tương tác với Gen AI và cách khắc phục nó qua Prompt
  • Điều Gì Xảy Ra Nếu… Những Người Dệt Mã Trở Thành Những Người Bảo Vệ Cuối Cùng Của Sự Sáng Tạo?

You may also like:

  • KeyPath trong 10 phút - Swift
    KeyPath
  • Phù thủy phiên dịch ý tưởng
    feature_bg_blog_005
  • Autoresizing Masks trong 10 phút
    cropped-feature_bg_3.jpg
  • Dispatch Semaphore trong 10 phút
    Semaphore
  • Raw String trong 10 phút
    Raw String

Archives

  • 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)

About me

Education, Mini Game, Digital Art & Life of coders
Contacts:
contacts@fxstudio.dev

Fx Studio

  • Home
  • About me
  • Contact us
  • Mail
  • Privacy Policy
  • Donate
  • Sitemap

Categories

  • Art (1)
  • Blog (44)
  • Code (11)
  • Combine (22)
  • Flutter & Dart (24)
  • iOS & Swift (102)
  • No Category (1)
  • RxSwift (37)
  • SwiftUI (80)
  • Tutorials (87)

Newsletter

Stay up to date with our latest news and posts.
Loading

    Copyright © 2025 Fx Studio - All rights reserved.