【iOS - Singleton(單例設計模式)】

Singleton 是一種設計模式且適用於任何 OOP 的程式語言,它的精神在於節省記憶體的使用量,但這時又會有人說,記憶體真的有珍貴到這種地步嗎?所以,又有另外一種精神衍生出來,那就是唯一性,也就是在整個應用程式的生命週期中永遠都只會存在一個實體,在 iOS 的設計中很常見唯一性,像是 UIApplication,應該是永遠只會有一個吧!再者還有 UIScreen 也是永遠只有一個!所以,當我們在設計類別時,首先應該思考的是它的特性,再來決定我們是否要使用 Singleton 來設計。或許這樣說,大家還不是很清楚,法蘭克就舉幾個適合不適合的例子來說明好了。

適合:

  • 專門用來跟資料庫溝通的類別(DataAccessObject),又或者是處理字串的工具包(StringUtils)。這兩種類型的類別因不管在 App 的哪一個功能裡它都可以是同一個實體。
  • 具唯一性的環境配置檔。

不適合:

  • 直接舉 Apple 所提供的類別來說明,例如 UIView、UILabel 該類型的類別就不適合使用 Singleton,因為該類型的類別都違反了唯一性,也就是說在同一個畫面裡的每一個 UILabel 都應該會是不同的實體,每個實體在使用前都必須個別生成的。

Singleton 是否符合多執行緒的安全呢?Swift3 前的寫法上(dispatch_once)有些許的不同,但法蘭克就不再追溯之前的寫法了。而提到多執行緒安全,這又衍生出兩個議題,一為在多執行緒下是否都是取到相同的實體呢?;二則為在多執行緒下處理 Singleton 裡的變數是否能保證絕對安全的呢?文章始,會針對前項來撰寫實例證明之,而文末,則來說明如何保證 Singleton 裡的變數是多執緒安全的。


▼產生一個 Single View Application 的專案

▼將專案名稱命名為 SingletonDemo

▼新增一個 DataAccessObject.swift 檔並撰寫 Singleton 的邏輯

如上建立了符合 Singleton 的類別,但法蘭克剛剛在前言有說道在 Swift3 之前為了符合執行緒安全的狀況下(也就是同時開啟多執行緒來取得該物件時,都要取到同一個物件),寫法會有些許的不同(可參考),但在 Swift3 Apple 大大的簡化了其寫法,說明如下。

如上說明,法蘭克使用了 static properties 的修飾字來定義變數,以符合執行緒安全(最後法蘭克會撰寫實例來驗證之),先來說明以上的程式碼範例。

第 5 行 => 透過 sharedInstance 變數來取得該類別的實例。宣告為 static 可直接透過物件 +「.」運算子來取得該實例。

第 7 ~ 9 行 => 初始化這個物件的建構子。在這邊宣告成 private(私有) 是因為只能在該類別裡生成,也就是目前的設計僅能讓 sharedInstance() 來生成,不能從外部去生成它。在這裡必須 override(覆寫) 掉父類別的建構子。

第 11 ~ 13 行 => 該物件銷毀的時侯會執行該區塊的程式碼,用來觀察物件被銷毀的時機點。

第 15~ 17 行 => 用來測試 Singleton 的方法。

▼在 ViewController的ViewDidLoad 方法下開啟三條執行緒來測試是否符合Singleton的設計模式

在 ViewDidLoad 加入以下程式碼後,啟動模擬器來測試看看:

執行的結果 console 會如下:

在這邊我們看到當呼叫 loadDatas() 時會執行 init,當再次呼叫該類的 loadDatas(),並不會再生成新的物件,如此就是 Singleton 的精神所在。最後,法蘭克要來說明 Singleton 如何保證裡頭的變數是多執緒安全的。

▼在 DataAccessObject.swift 檔下撰寫保證裡頭的變數是多執緒安全的的邏輯

第 7 行 => 初始化 DispatchQueue 以用來處理 Singleton 裡保證多執行緒安全的變數。

第 8 行 => getter 和 setter 的變數

第 10 行=> 宣告一用來被外部類別存取的變數。

第 19~ 23 行 => 使用 Synchronous(同步的) 的方式取得變數。

第 17~ 22 行 => 使用 Asynchronous(非同步的) 的方式設定變數,並使用 barrier flag 告訴佇列,這個特定工作項目,必須在沒有其他平行執行的項目時執行,以確保證執行緒安全。


如果您喜歡我的文章,請多按幾下「拍手」給我鼓勵,或是按「follow」讓我持續提供好文章給您。

    法蘭克的iOS世界

    Written by

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade