iOS常用的Design Pattern

閱讀時間約 10 分鐘

記錄個人常用的Design Pattern,之前面試被問到有用過哪些,瞬間一片空白🥹

以下有寫iOS應該都用過,只是可能講不出這算哪個Pattern

MVC vs. MVVM

詳情在前一篇學習筆記

單例模式 Singleton

確保一個class只能創建一個實例,並提供全域訪問。一般我會用在單一狀態管理上,例如:資料庫連結、登入狀態管理

通常包含以下特點:

  1. 私有構造函數(Private Constructor): Singleton類別的init通常是私有的,以防止外部代碼通過實例化多個對象。
  2. 靜態實例(Static Instance): Singleton類別包含一個靜態成員,用於保存該類別的唯一實例。
  3. 全域訪問點(Global Access Point): 提供一個全域的訪問點,使得其他程式碼可以獲取Singleton實例的引用。

範例:管理登入狀態的Manager。

class LoginManager {
static let shared = LoginManager()
var isLogin = false

private init() {}

func login() {
isLogin = true
}

func logout() {
isLogin = false
}
}


委派模式 Delegation pattern

一個物件把一些職責讓另一個物件來執行。這個Apple官方自己也很常用。

範例:UITableViewDelegate,把TableView的一些行為(如:點擊)給ViewController來代理

class VC1: UIViewController{
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
tableView.delegate = self
}
}

extension VC1: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// 點擊後讓VC做一些事
}
}


觀察者模式 Observer Pattern

通知:Notification

這個Apple官方也很常用,例如:鍵盤彈起(UIKeyboardWillShowNotification)收合(UIKeyboardWillHideNotification),或是AppDelegate各種生命週期通知。

這種通知是全域的,發布者不需要知道訂閱者的任何資訊。

鍵值觀察:Key-Value Observing (KVO)

一種機制,允許一個物件可以註冊監聽其他物件指定屬性的變化。

這邊要介紹一下Combine的KVOpublisher(for: \.KeyProperty),我覺得在UIKit上超好用ㄉ

範例:監聽UITabBarController的TabBar.isHidden

import Combine
class MyTabBarController: UITabBarController {
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
setBinding()
}

private func setBinding() {
self.tabBar.publisher(for: \.isHidden).sink { [weak self] hidden in
if !hidden {
// 如果Tabbar可見,在Bar上show一條InfoView
self?.showInfoView()
} else {
// 反之隱藏
self?.hideInfoView()
}
}
}.store(in: &subscriptions)
}

Delegate 和 Notification 使用時機

兩個都可以拿來在App裡通訊傳值,但使用時機略有不同

Delegate 的使用時機

  • 一對一:通常是一個委託人對到一個委託對象。
  • 有明確的行為:通常會訂個protocol,讓委託對象實現其中的方法,以達到客製化行為的目的。

Notification 的使用時機

  • 一對多:一個發送通知的對象可以通知多個觀察者。
  • 非特定行為: Notification 通常用於通知一個事件的發生,而不關心具體的行為。多個不同的觀察者可以對同一事件進行不同的反應。

Delegate可不可以一對多?

也可以。通常是一對一,如果要一對多,自己寫Array來保存多個觀察者。通常我會用在有明確行為,又只有兩三個地方需要接受這個訊息的情況下。

範例:Socket連線,當Socket連線狀態產生變化時,要通知底下所有有註冊他的委託對象(聊天室列表&聊天室頁面)​

// 觀察者
class WeakSocketObserver {
weak var value: SocketDelegate?
init (value: SocketDelegate) {
self.value = value
}
}

// 定義Socket連線狀態的協議
protocol SocketDelegate: AnyObject {
// 連線成功
func didConnected()
// 其他狀態省略
// ...
}

Socket本人(委託人)

import SocketIO
@objc class MySocket: NSObject {
@objc static let shared = MySocket()
private var manager: SocketManager()
private var socket: SocketIOClient!
// 所有觀察者
private var observers: [WeakSocketObserver] = []

private override init() {
super.init()
// ...
socket = manager.defaultSocket
socket.on(clientEvent: .connect) { (data, ack) in
// 連線成功時,通知所有觀察者
self.observers.forEach { (observer) in
observer.value?.didConnected()
}
}
}


func tryConnect() {
// 開始連線
}
}

加入委託對象(觀察者)

// 第一個觀察者​-聊天列表
class ChatroomListVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Socket加入觀察者
MySocket.shared.add(WeakSocketObserver(value: self))
// 嘗試連線
MySocket.shared.tryConnect()
}
}

extensionChatroomListVC: SocketDelegate {
func didConnected() {
// 我連線了!
}
}

// 第二個觀察者​​-聊天室
class ChatroomVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Socket加入觀察者
MySocket.shared.add(WeakSocketObserver(value: self))
// 嘗試連線
MySocket.shared.tryConnect()
}
}

extensionChatroomVC: SocketDelegate {
func didConnected() {
// 我連線了!
}
}

Socket連線後,底下的聊天室跟聊天列表都會收到通知。




參考資料:

ChatGPT

https://wilden-chen.gitbook.io/swift-design-patterns



avatar-img
6會員
35內容數
紀錄iOS開發上遇到的問題或是一些流程筆記。主要都是Swift。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Michelle Chen的沙龍 的其他內容
本文紀錄了MVC和MVVM的差異,包括各自的優缺點和最大差異,並討論了MVVM的商業邏輯應該寫在哪的問題。
在寫SwiftUI view的時候,碰到一個瓶頸(? 帶有Binding的參數要如何preview。 舉例來說有個右邊圖片左邊文字的View,給他一個@Binding var isActive: Bool的狀態,當active時圖片要跟著改變: struct RightImageView: Vie
雖然我之前文章大力讚美SwiftUI的tabView有多好用,無奈專案大部分都是UIKit啊~~~~要在既有專案用Tab架構只能用UITabBarController了 設計這次還出了一個超複雜的UI,陰影+圓角+客製化高度 大套餐 馬上開始吧。 圓角+陰影 重點就是subclass一個
Sandbox 架構 /Documents:主要用於儲存用戶生成的數據或者不能重新創建的數據。這些可能包括由你的應用程式創建的文件、從服務器下載的文件、用戶在應用程式中創建或修改的數據等。 這些數據在應用程式的生命週期中是持久保存的,即使應用程式被終止或者系統重啟,這些數據也會保留。此外
SwiftUI的TabView實在太好用啦!我要大大的推廣他ლ(╹◡╹ლ) 換頁+小圓點滑動 無限自動輪播 底部Tabbar
這個浮誇標題是ChatGPT幫我想的😊 圖也是DALL幫我產的, AI萬歲! GCD也是面試必問題啊!我答超爛的,只會用背景呼叫API+切Main Thread更新畫面,今天就來認真了解。 GCD是什麼? 先來問ChatGPT什麼是GCD? GCD,全名 Grand Central Dis
本文紀錄了MVC和MVVM的差異,包括各自的優缺點和最大差異,並討論了MVVM的商業邏輯應該寫在哪的問題。
在寫SwiftUI view的時候,碰到一個瓶頸(? 帶有Binding的參數要如何preview。 舉例來說有個右邊圖片左邊文字的View,給他一個@Binding var isActive: Bool的狀態,當active時圖片要跟著改變: struct RightImageView: Vie
雖然我之前文章大力讚美SwiftUI的tabView有多好用,無奈專案大部分都是UIKit啊~~~~要在既有專案用Tab架構只能用UITabBarController了 設計這次還出了一個超複雜的UI,陰影+圓角+客製化高度 大套餐 馬上開始吧。 圓角+陰影 重點就是subclass一個
Sandbox 架構 /Documents:主要用於儲存用戶生成的數據或者不能重新創建的數據。這些可能包括由你的應用程式創建的文件、從服務器下載的文件、用戶在應用程式中創建或修改的數據等。 這些數據在應用程式的生命週期中是持久保存的,即使應用程式被終止或者系統重啟,這些數據也會保留。此外
SwiftUI的TabView實在太好用啦!我要大大的推廣他ლ(╹◡╹ლ) 換頁+小圓點滑動 無限自動輪播 底部Tabbar
這個浮誇標題是ChatGPT幫我想的😊 圖也是DALL幫我產的, AI萬歲! GCD也是面試必問題啊!我答超爛的,只會用背景呼叫API+切Main Thread更新畫面,今天就來認真了解。 GCD是什麼? 先來問ChatGPT什麼是GCD? GCD,全名 Grand Central Dis
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
iOS的官方ChatGPT上線,plus會員無限制使用,相比每三小時25條,那可真是笑暈在廁所了。 如果有需要安裝註冊教程可以評論去留個言,我看看人多就出一個教程
Thumbnail
Android 應用程式開發的50 個提示 Android程式碼審查與優化: 程式碼審查建議:“建議對此程式碼片段進行改進:[此處的程式碼片段]。” 性能優化:“建議優化此程式碼性能的方法:[此處的程式碼片段]。” 程式碼重構建議:“推薦重構此程式碼的最佳實踐:[此處的程式碼片段]。”
Thumbnail
2021年想要保持的小習慣就是,記錄每天的自己有沒有喝到足量的水,所以我使用了健康跟捷徑這兩個蘋果原生的軟體,來真實記錄自己每天的喝水狀況。
Thumbnail
一張圖讓你搞懂IOS 14.7更新的內容 IOS 14.7於今日開放更新,這次更新又多了那些內容呢? 就讓皓哥3C為大家簡單整理介紹一下囉~
Thumbnail
有一天朋友傳了條訊息給我,說:身份證上浮水印好麻煩喔,要用線上網頁做,搞好久。 我回:你怎麽不問我啦,我教你阿,超簡單耶! 原來友人為了上傳保險資料(話說最近防疫保險有夠夯),又有個資上的顧慮,才有了以上的對話。接下來想教大家蘋果手機內建的「照片」功能,就能簡簡單單做出浮水印的效果嘍。
Thumbnail
今天要和大家介紹如何用 IOS 內建的螢幕錄影功能搭配 PDF 做教學影片!然後還會介紹不用下載任何 APP 就能編輯影片的超實用功能!
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
iOS的官方ChatGPT上線,plus會員無限制使用,相比每三小時25條,那可真是笑暈在廁所了。 如果有需要安裝註冊教程可以評論去留個言,我看看人多就出一個教程
Thumbnail
Android 應用程式開發的50 個提示 Android程式碼審查與優化: 程式碼審查建議:“建議對此程式碼片段進行改進:[此處的程式碼片段]。” 性能優化:“建議優化此程式碼性能的方法:[此處的程式碼片段]。” 程式碼重構建議:“推薦重構此程式碼的最佳實踐:[此處的程式碼片段]。”
Thumbnail
2021年想要保持的小習慣就是,記錄每天的自己有沒有喝到足量的水,所以我使用了健康跟捷徑這兩個蘋果原生的軟體,來真實記錄自己每天的喝水狀況。
Thumbnail
一張圖讓你搞懂IOS 14.7更新的內容 IOS 14.7於今日開放更新,這次更新又多了那些內容呢? 就讓皓哥3C為大家簡單整理介紹一下囉~
Thumbnail
有一天朋友傳了條訊息給我,說:身份證上浮水印好麻煩喔,要用線上網頁做,搞好久。 我回:你怎麽不問我啦,我教你阿,超簡單耶! 原來友人為了上傳保險資料(話說最近防疫保險有夠夯),又有個資上的顧慮,才有了以上的對話。接下來想教大家蘋果手機內建的「照片」功能,就能簡簡單單做出浮水印的效果嘍。
Thumbnail
今天要和大家介紹如何用 IOS 內建的螢幕錄影功能搭配 PDF 做教學影片!然後還會介紹不用下載任何 APP 就能編輯影片的超實用功能!