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
7會員
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
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
在 iOS 18 中,許多用戶發現截圖後的照片顏色過於鮮豔,看起來比實際情況還要更飽和、甚至有些不真實。 這個問題不僅影響照片的真實呈現,還可能讓圖像顯得有些刺眼。 幸運的是,這個問題其實是可以輕鬆解決的!在這篇文章中, 我將教你如何快速調整 iOS 18 截圖中的顏色飽和度,讓圖片回歸自然、
Thumbnail
隨著科技的進步,智能手機已成為日常生活中不可或缺的一部分, 然而,長時間的高音量使用對聽力的影響不容忽視。為了幫助用戶保護聽力, Apple 在 iOS 18.2 中推出了一項全新的功能:音量最大上限設定。 聽力保護的重要性 長期使用的風險:探討長時間高音量使用耳機或手機對聽力的影響
Thumbnail
蘋果最新釋出的 iOS 18.2 更新已經正式到來,這次的更新不僅包含了大量的性能提升, 還有一些令人期待的新功能和系統變化。從細節改善到功能強化, 這次更新無疑是為了提升使用者的整體體驗。無論你是iPhone的忠實粉絲, 還是對新功能充滿好奇,這篇文章將幫助你快速了解 iOS 18.2 的所
Thumbnail
蘋果近日正式推出了 iOS 18.2 更新,原本讓人期待的新版系統, 卻意外成為了不少用戶的「災難更新」。許多升級後的用戶紛紛反映, 手機出現了各種問題,包括應用崩潰、系統卡頓、電池消耗異常等, 讓人不禁質疑這次更新是否真的值得。 究竟是哪些問題讓 iOS 18.2 成為了困擾許多人的「更新
Thumbnail
隨著 iOS 18.2 的推出,蘋果再次為我們的設備帶來了令人期待的全新功能——自然語言搜尋。 這項功能的引入,讓我們在使用 Apple Music 和 Apple TV 時,能夠更加直觀且高效地進行內容搜尋。 不再需要精確的關鍵字或複雜的搜尋條件,只需像與朋友聊天般自然地表達需求, iPho
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
MVI(Model View Intent),特點是Intent。 Model 負責介面狀態 View 負責顯示資料。 Intent 負責將封裝後的操作告知Model。
MVVM(Model View ViewModel),特點是View跟ViewModel之間做資料綁定。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。
Thumbnail
樣板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
在 iOS 18 中,許多用戶發現截圖後的照片顏色過於鮮豔,看起來比實際情況還要更飽和、甚至有些不真實。 這個問題不僅影響照片的真實呈現,還可能讓圖像顯得有些刺眼。 幸運的是,這個問題其實是可以輕鬆解決的!在這篇文章中, 我將教你如何快速調整 iOS 18 截圖中的顏色飽和度,讓圖片回歸自然、
Thumbnail
隨著科技的進步,智能手機已成為日常生活中不可或缺的一部分, 然而,長時間的高音量使用對聽力的影響不容忽視。為了幫助用戶保護聽力, Apple 在 iOS 18.2 中推出了一項全新的功能:音量最大上限設定。 聽力保護的重要性 長期使用的風險:探討長時間高音量使用耳機或手機對聽力的影響
Thumbnail
蘋果最新釋出的 iOS 18.2 更新已經正式到來,這次的更新不僅包含了大量的性能提升, 還有一些令人期待的新功能和系統變化。從細節改善到功能強化, 這次更新無疑是為了提升使用者的整體體驗。無論你是iPhone的忠實粉絲, 還是對新功能充滿好奇,這篇文章將幫助你快速了解 iOS 18.2 的所
Thumbnail
蘋果近日正式推出了 iOS 18.2 更新,原本讓人期待的新版系統, 卻意外成為了不少用戶的「災難更新」。許多升級後的用戶紛紛反映, 手機出現了各種問題,包括應用崩潰、系統卡頓、電池消耗異常等, 讓人不禁質疑這次更新是否真的值得。 究竟是哪些問題讓 iOS 18.2 成為了困擾許多人的「更新
Thumbnail
隨著 iOS 18.2 的推出,蘋果再次為我們的設備帶來了令人期待的全新功能——自然語言搜尋。 這項功能的引入,讓我們在使用 Apple Music 和 Apple TV 時,能夠更加直觀且高效地進行內容搜尋。 不再需要精確的關鍵字或複雜的搜尋條件,只需像與朋友聊天般自然地表達需求, iPho
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
MVI(Model View Intent),特點是Intent。 Model 負責介面狀態 View 負責顯示資料。 Intent 負責將封裝後的操作告知Model。
MVVM(Model View ViewModel),特點是View跟ViewModel之間做資料綁定。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。
Thumbnail
樣板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。