Swift — Singleton Pattern(單例模式)筆記

Tom Tung
Jun 19, 2021

--

單例模式是什麼?

精神在於整個應用程式只有一個實體存在,意味著此實體被共享著。 而他的生命週期從應用程式一啟動就開始了,直到應用程式被銷毀。

基本要求:

  • 只能有一個實例。
  • 必須自己創建自己的唯一實例。
  • 必須給所有其他對象提供這一實例。

iOS 中的單例模式

  • UIApplication.shard :每個應用程序有且只有一個UIApplication實例,由UIApplicationMain函數在應用程序啟動時創建為單例對象。
  • URLSession.shared:管理網絡連接。
  • NotificationCenter.defualt:管理 iOS 中的通知。
  • UserDefaults.standard:存儲輕量級的本地數據。

優點:

  • 提供對唯一實例的受控訪問: 防止其他對象對自己實例化,確保所有對象都訪問同一個實例。
  • 節約系統資源:由於只存在一個對象,因此可以節約系統資源。
  • 伸縮性:自己控制實例化的進程,因此易於修改。

缺點:

單例狀態的混亂

由於單例是共享的,所以使用單例時,無法清楚知道單例當前的狀態。

ex. 當用戶登錄,由一個實例負責當前用戶的各項操作。但由於共享,當前用戶的狀態可能已經被其他實例改變,而原來實例仍不知道改變了。

測試困難

主要由於單例狀態的混亂所造成。因為單例狀態可以被其他人所修改,所以進行測試時,很難從一個乾淨的狀態開始。

單例訪問的混亂

由於單例是全局的,所以無法對訪問權限作限定,容易造成管理上的混亂。

實作

第一種方式

(line 14) 在 class 中實例化自己,然後在前面加上 static 使其變為 type property,能使 MyManager 還沒實例化就能取得 shared 這個屬性。
shared 實例化了 MyManager ,可以取得 MyManager 裡頭的屬性及方法。

(line 20) 在 init 前加上 private ,確保不會再被生成。

執行結果

可以發現到 MyManager 只被實例化一次,之後都是共享同一個實例。

第二種方式

第二種是第一種的變形,更加複雜。讓單例在 closure 中初始化,同時加入 class func 來獲取單例。

第二種方式雖然複雜,但可以在 closure 中作一些額外的配置。

調用的方式和第一種不太一樣,需使用 shared()

print(MyManager.shared().name)

--

--

Tom Tung

Hi, I’m Tom. I work as an iOS developer.