12/08/2018, 15:47

Cách viết một Singleton sao cho đúng trong lập trình IOS với Swift

Trong lập trinh IOS chẳng mấy xa lạ với design pattent Singleton. Nhưng đã bao giờ bạn thực sự để ý cách viết và sử dụng nó sao cho thực sự hợp lý. Trong bài này chúng ta cùng nhau tìm hiểu cách viết và sử dụng singleton trong lập trình IOS cụ thể là ngôn ngữ swift sao cho đúng và hợp lý. Về cơ bản ...

Trong lập trinh IOS chẳng mấy xa lạ với design pattent Singleton. Nhưng đã bao giờ bạn thực sự để ý cách viết và sử dụng nó sao cho thực sự hợp lý. Trong bài này chúng ta cùng nhau tìm hiểu cách viết và sử dụng singleton trong lập trình IOS cụ thể là ngôn ngữ swift sao cho đúng và hợp lý. Về cơ bản có 3 điều cần nhớ về singleton:

  1. Singleton phải là duy nhất. Tức là chỉ có duy nhất một thể hiện trong suốt vòng đời của ứng dụng. Nó được xậy dựng như một biến global.
  2. Để singleton là duy nhất thi khi khởi tạo cần được private.
  3. Từ lưu ý số 1, chỉ cho phép có một instance được tạo ra trong suốt quá trình chạy ứng dụng, điều này có nghĩa nó cần một thread an toàn. Nếu một singleton được tạo ra không chính xác trong code, bạn có thể sẽ có 2 thread cùng khở tạo một singleton tại cùng một thời điểm. Điều này khiến nó không còn là duy nhất trừ khi chúng ta đưa nó vào một thread an toàn. Cách giải quyết ở đây là đưa hàm khởi tạo vào một dispatch_once GCD block. Nó giúp đảm bảo rằng singleton chỉ được chạy một lần duy nhất. Bây giờ chúng ta cùng đi qua các cách để tạo ra một singleton thông qua các giai đoạn bằng ngồn ngữ swift Swift 1.0 Đây là thời điểm khi swift mới ra đời. Chưa có nhiều hỗ trợ và ảnh hưởng nhiều bởi objective-C. Một ví dụ đơn giản
class TheOneSingleton {
    class var sharedInstance: TheOneSingleton {
        struct Static {
            static var oneToken: dispatch_once_t = 0
            static var instance: TheOneSingleton? = nil
        }
        dispatch_once(&Static.oneToken) {
            Static.instance = TheOneSingleton()
        }
        return Static.instance!
    }
}

Đây là một cách viết điển hình hồi đó và có thể dễ dàng tim ra trên các nguồn khác nhau. Nhưng đây là cách viết khá tệ vì nó đi ngược lại các phương châm cơ bản của ngôn ngữ swift: terse and expressive Sử dụng struct Để khắc phục các nhược điểm trên, thời điểm này họ sử dụng một phương pháp khác. Bằng cách lồng thêm struct vào. Cách này tuy cũ nhưng đến nay vẫn thi thoảng được dùng.

class TheOneSingleton {
    class var sharedInstance: TheOneSingleton {
        struct Static {
            static let instance = TheOneSingleton()
        }
        return Static.instance
    }
}

Cách viết này cơ bản khắc phục được các nhược điểm của cách đầu tiên, tuy nhiên nó chỉ là tối ưu nhất tại thời điểm đó mà thôi. One Line Singleton Bắt đầu từ swift 1.2. Xuất hiện một cách để viết một singleton ngắn gọn hơn rất nhiều. Đó là sử dụng biết global.

class TheOneSingleton {
    class var sharedInstance: TheOneSingleton {
        return shared
    }
}
private let shared = TheOneSingleton()

Có một điều đặc biệt rằng tại sao ở đây chúng ta không còn thấy dispatch_once. Nhưng đầy là điều apple muốn. https://developer.apple.com/swift/blog/?id=7 Đoạn trích dẫn sau chứng minh rằng chúng được gói trong một dispatch_once

“The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed, and is launched as `dispatch_once` to make sure that the initialization is atomic. This enables a cool way to use `dispatch_once` in your code: just declare a global variable with an initializer and mark it private.”
— Apple's Swift Blog

Tuy nhiên với cách viết này đưa khiến chúng ta gắp vấn đề khi đặt tên, trùng tên biến. Điều này khiến một cách tối ưu được đưa ra

class TheOneSingleton {
    static let sharedInstance = TheOneSingleton()
}

Rõ ràng hơn nữa là kể từ swift 3 dispatch_once không còn được hỗ trợ nữa. Tuy nhiên để đảm bảo tính duy nhất của singleton bạn đừng quên private phương thức khởi tạo của class nhé

class TheOneSingleton {
    static let sharedInstance = TheOneSingleton()
    private init() {}
}

Điều này ngăn cản người khác có thể sử dụng phương thức khởi tạo default để phá vỡ tinh duy nhất của singleton Kết Luận Trong phần này mình đã nói về một số cách để viết ra một singleton sử dụng swift, Tuy nhiên với bạn có thể chứng mình cả 3 phương pháp đều chỉ khởi tạo một lần bằng cách đưa cả 3 phương pháp này vào source code đặt debug để kiểm tra. Nếu có thắc mắc gì vui long comment bên dưới nhé.

Bài liên quan

[C#] Lưu thông tin cấu hình ứng dụng trong lập trình C#

Bài viết hôm nay, mình xin hướng dẫn các bạn các cách lưu thông số cấu hình trong ứng dụng Window form bằng lập trình C#. Vậy lưu thông số cấu hình ứng dụng C# là gì? Ví dụ đơn giản, khi các bạn mở một file nhạc từ ứng dụng của bạn, khi các bạn ...

Hoàng Hải Đăng viết 2 tuần trước

Một số thủ thuật trong lập trình iOS (Part 2)

Xin chào tất cả các bạn, một tháng trôi qua nhanh quá, dù muốn hay không thì tôi lại quay trở lại với các bạn đây

Trần Trung Dũng viết 23:40 ngày 15/09/2018

Ứng dụng BDD trong lập trình iOS

Testing đóng 1 vai trò quan trọng trong quá trình phát triển phần mềm. Hôm nay tôi sẽ giới thiệu với các bạn ứng dụng BDD test trong lập trình iOS. Giả sử ta muốn test 1 phép cộng đơn giản: File H // // ViewController.h // HelloKiwi // // Created by nguyen hai dang on 1/23/15. // ...

Trịnh Tiến Mạnh viết 15:53 ngày 07/09/2018

Quy tắc viết mã cơ bản trong lập trình web với PHP

Để có thể học php tốt thì điều quan trọng đầu tiên là bạn phải nắm vững được quy tắc viết mã cơ bản trong lập trình web với php. Vì trong lập trình chỉ cần bạn viết sai một ký tự nhỏ dù là dấu phẩy (,) thì chương trình của bạn không bao giờ có thể hoạt động được. Bài viết hôm nay mình ...

Hoàng Hải Đăng viết 10:20 ngày 20/08/2018

Một số thủ thuật trong lập trình iOS (Part 1)

Nếu bạn đang không biết project của mình build trong vòng bao lâu, bạn có thể enable tính năng hiển thị build time trên Xcode bằng cách thực hiện câu lệnh sau trong Terminal: defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES Kết quả thu được sẽ như sau: Trong Release ...

Bùi Văn Nam viết 18:01 ngày 19/08/2018
0