Combine的介紹與使用

目錄

  • 一、Combine 框架介紹
  • 二、核心概念
  • 三、基礎使用示例
    • 3.1、創建 Publisher & 訂閱
    • 3.2、操作符鏈式調用
    • 3.3、Subject 使用(手動發送值)
    • 3.4、網絡請求處理
    • 3.5、組合多個 Publisher
    • 3.6、錯誤處理
  • 四、核心操作符速查表 Operator
  • 五、UIKit 綁定示例
  • 六、SwiftUI 集成示例
  • 七、最佳實踐建議

一、Combine 框架介紹

Combine 是 Apple 在 2019 年推出的聲明式響應式編程框架,專為 Swift 設計,深度集成在 Apple 生態系統中(iOS 13+,macOS 10.15+)。它提供了一套統一的 API 來處理隨時間變化的數據流,特別適合處理異步事件、數據綁定和復雜的狀態管理。

二、核心概念

  1. Publisher:數據生產者(發布事件)
  2. Subscriber:數據消費者(接收事件)
  3. Operator:數據轉換操作符
  4. Subject:可手動發送值的特殊 Publisher
  5. Scheduler:線程調度管理器

三、基礎使用示例

3.1、創建 Publisher & 訂閱

import Combinevar cancellables = Set<AnyCancellable>()// 創建 Publisher
let stringPublisher = Just("Hello Combine!") // 發送單個值
let arrayPublisher = [1, 2, 3].publisher    // 發送序列值// 訂閱 Publisher
stringPublisher.sink(receiveCompletion: { completion inswitch completion {case .finished: print("Completed")case .failure(let error): print("Error: \(error)")}},receiveValue: { value inprint(value) // "Hello Combine!"}).store(in: &cancellables) // 存儲訂閱

3.2、操作符鏈式調用

[1, 2, 3, 4, 5].publisher.filter { $0 % 2 == 0 }     // 過濾偶數.map { $0 * 10 }            // 轉換值.sink { print($0) }         // 接收值.store(in: &cancellables)/* 輸出:
20
40
*/

3.3、Subject 使用(手動發送值)

// PassthroughSubject:不保存當前值
let passSubject = PassthroughSubject<String, Never>()// CurrentValueSubject:保存當前值
let currentSubject = CurrentValueSubject<Int, Never>(0)// 訂閱
passSubject.sink { print("收到: \($0)") }.store(in: &cancellables)// 發送值
passSubject.send("第一次發送")
passSubject.send("第二次發送")// 修改當前值
currentSubject.value = 5
currentSubject.send(10) // 發送新值

3.4、網絡請求處理

struct User: Decodable {let name: String
}func fetchUser() -> AnyPublisher<User, Error> {let url = URL(string: "https://api.example.com/user")!return URLSession.shared.dataTaskPublisher(for: url).map(\.data) // 提取數據.decode(type: User.self, decoder: JSONDecoder()) // 解碼.receive(on: DispatchQueue.main) // 切換到主線程.eraseToAnyPublisher() // 類型擦除
}// 使用
fetchUser().sink(receiveCompletion: { print($0) },receiveValue: { user inprint("用戶名: \(user.name)")}).store(in: &cancellables)

3.5、組合多個 Publisher

let usernamePublisher = PassthroughSubject<String, Never>()
let passwordPublisher = PassthroughSubject<String, Never>()// 組合最新值
Publishers.CombineLatest(usernamePublisher, passwordPublisher).map { username, password in!username.isEmpty && password.count >= 6}.sink { isValid inprint("表單有效? \(isValid)")}.store(in: &cancellables)// 觸發驗證
usernamePublisher.send("user")
passwordPublisher.send("123")   // 輸出: false
passwordPublisher.send("123456") // 輸出: true

3.6、錯誤處理

enum CustomError: Error { case test }Fail(error: CustomError.test) // 立即發送錯誤的Publisher.catch { error -> Just<String> inprint("捕獲錯誤: \(error)")return Just("默認值")}.sink(receiveValue: { print($0) }).store(in: &cancellables)/* 輸出:
捕獲錯誤: test
默認值
*/

四、核心操作符速查表 Operator

操作符功能描述
map值轉換
filter條件過濾
flatMap展平嵌套Publisher
combineLatest組合多個Publisher的最新值
merge合并多個Publisher
debounce防抖動(用于搜索輸入)
throttle節流(控制事件頻率)
retry失敗重試
switchToLatest切換到最新Publisher

五、UIKit 綁定示例

class ViewController: UIViewController {@IBOutlet weak var textField: UITextField!@IBOutlet weak var label: UILabel!private var cancellables = Set<AnyCancellable>()override func viewDidLoad() {super.viewDidLoad()// 創建文本框內容Publisherlet textPublisher = NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: textField).compactMap { ($0.object as? UITextField)?.text }// 綁定到標簽textPublisher.filter { $0.count > 3 }.map { "輸入: \($0)" }.assign(to: \.text, on: label).store(in: &cancellables)}
}

六、SwiftUI 集成示例

import SwiftUI
import Combinestruct ContentView: View {@StateObject private var viewModel = ViewModel()var body: some View {VStack {TextField("搜索", text: $viewModel.searchText)List(viewModel.results, id: \.self) { item inText(item)}}}
}class ViewModel: ObservableObject {@Published var searchText = ""@Published var results: [String] = []private var cancellables = Set<AnyCancellable>()init() {$searchText.debounce(for: .seconds(0.5), scheduler: RunLoop.main).removeDuplicates().flatMap { query -> AnyPublisher<[String], Never> inself.search(query: query)}.assign(to: \.results, on: self).store(in: &cancellables)}func search(query: String) -> AnyPublisher<[String], Never> {// 模擬網絡請求let results = query.isEmpty ? [] : ["\(query)結果1", "\(query)結果2"]return Just(results).eraseToAnyPublisher()}
}

七、最佳實踐建議

  1. 內存管理:始終使用 store(in: &cancellables) 管理訂閱生命周期
  2. 線程切換:使用 receive(on:) 確保在正確線程更新 UI
  3. 錯誤處理:合理使用 catch, retry 等操作符
  4. 避免強引用:使用 [weak self] 防止循環引用
  5. 調試技巧:使用 print() 操作符跟蹤事件流

注意:Combine 要求最低系統版本 iOS 13+/macOS 10.15+。對于支持舊系統的項目,可考慮使用 RxSwift 或其他響應式框架。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88830.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88830.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Java筆記】七大排序

目錄1. 直接插入排序2. 希爾排序3. 選擇排序4. 堆排序(重要)5. 冒泡排序6. 快速排序&#xff08;重要&#xff09;6.1 Hoare 法6.1.1 Hoare 法優化6.2 挖坑法&#xff08;重點&#xff09;6.3 快速排序的非遞歸寫法7. 歸并排序海量數據的排序問題8. 總結1. 直接插入排序 時間復…

H.264編解碼(NAL)

在我們的日常生活中&#xff0c;比如有緩存電影或者是發送視頻的需求。如果沒有視頻壓縮&#xff0c;一部手機只能存幾分鐘視頻&#xff0c;1TB 硬盤也裝不下幾部電影&#xff0c;用 4G 網絡發一段 1 分鐘視頻&#xff0c;可能需要幾十分鐘&#xff08;甚至傳不完&#xff09;&…

新手向:Python自動化辦公批量重命名與整理文件系統

本文將詳細介紹如何使用Python實現一個強大的文件批量重命名與整理工具&#xff0c;幫助開發者自動化這一繁瑣過程。本教程面向Python初學者&#xff0c;通過一個完整的項目案例&#xff0c;講解文件系統操作的核心技術。我們將構建的工具將具備以下功能&#xff1a;基于正則表…

C++ 左值右值、左值引用右值引用、integral_constant、integral_constant的元模板使用案例

C 左值右值、左值引用右值引用、integral_constant、integral_constant的元模板使用案例一、左值右值1.左值2.右值二、左值引用右值引用1.左值引用2.右值引用總結三、integral_constant四、integral_constant的元模板使用案例1.求最大整數2.內存對齊alignof關鍵字元模板計算內存…

c++算法一

1.雙指針總結&#xff1a;1.復寫0這道題&#xff0c;告訴我們要正難其反&#xff0c;我們從后向前進行重寫&#xff0c;刪除某些數字的時候&#xff0c;我們可以從前向后遍歷&#xff0c;但是增加一些數字的時候會對后面的數據進行覆蓋&#xff0c;所以要從后向前進行2.快樂數涉…

LeetCode-283. 移動零(Java)

283. 移動零 給定一個數組 nums&#xff0c;編寫一個函數將所有 0 移動到數組的末尾&#xff0c;同時保持非零元素的相對順序。 請注意 &#xff0c;必須在不復制數組的情況下原地對數組進行操作。 示例 1: 輸入: nums [0,1,0,3,12] 輸出: [1,3,12,0,0] 示例 2: 輸入: n…

【數據庫】慢SQL優化 - MYSQL

一、數據庫故障的關鍵點 引起數據庫故障的因素有操作系統層面、存儲層面&#xff0c;還有斷電斷網的基礎環境層面&#xff08;以下稱為外部因素&#xff09;&#xff0c;以及應用程序操作數據庫和人為操作數據庫這兩個層面&#xff08;以下稱內部因素&#xff09;。這些故障中外…

桶排序算法深度剖析

&#x1f50d; 桶排序算法深度剖析 &#x1f3af; 核心原理圖解?? 完整算法流程 #mermaid-svg-LyB6SpaZ132X4Wtn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-LyB6SpaZ132X4Wtn .error-icon{fill:#552222;}#mer…

對S32K144做的BMS安裝快速開發Simulink庫及BMS例程介紹

前言 本章介紹BMS硬件功能及SimuLink庫為主&#xff0c;捎帶介紹一些例程內容 注意&#xff1a;例程所用的協議均是自定義的 自做的SimuLink庫也會不定期更新 BMS例程的內容不定期維護添加 當前的BMS沒有主動均衡功能&#xff0c;這個有考慮后期加上&#xff0c;當前還處于…

urlencode、html實體編碼、unicode

目錄 urlencode html實體編碼 Unicode編碼 urlencode URL編碼也稱為百分號編碼&#xff0c;用于將URL中的特殊字符轉換為安全傳輸的格式。英文數字一般不編碼 特點&#xff1a; 使用%后跟兩個十六進制數字表示字符 空格編碼為或%20 保留字符&#xff08;; / ? : & …

【HarmonyOS】元服務概念詳解

【HarmonyOS】元服務概念詳解 最近幾年&#xff0c;我們手里的設備越來越多——手機、平板、手表、車機……光是管理這些設備上的APP就夠頭疼了&#xff1a;下載要流量、安裝占內存、換個設備又得重新弄一遍。有沒有更簡單的方式&#xff1f;HarmonyOS推出的“元服務”&#xf…

vscode/cursor怎么自定義文字、行高、顏色

JetBrains Mono: A free and open source typeface for developers | JetBrains: Developer Tools for Professionals and Teams 首先下載上面的文字&#xff0c;然后右鍵全選&#xff0c;安裝 然后重啟cursor 下載插件Apc Customize UI 點擊設置 把下面的代碼復制進去&…

JavaScript 與 C語言基礎知識差別

一&#xff0c; 變量聲明對比 C語言&#xff1a; int age 20; // 必須指定類型 float price 9.99; char grade A; const double PI 3.14; // 常量JavaScript&#xff1a; let age 20; // 數字 var price 9.99; // 現在不用&#xff0c;有缺點 co…

無縫矩陣支持音頻分離帶畫面分割功能的全面解析

一、技術原理與實現方式1. 音頻分離技術核心功能&#xff1a;HDMI無縫矩陣通過硬件或軟件實現音頻加嵌與分離功能&#xff0c;支持多設備音頻的獨立處理與增強。實現方式&#xff1a;音頻加嵌&#xff1a;將外部音頻信號&#xff08;如麥克風、調音臺&#xff09;嵌入HDMI信號中…

AI創作系列第18篇:海貍IM移動端UI統一大升級 - 從混亂到規范的技術重構之路

AI創作系列第18篇&#xff1a;海貍IM移動端UI統一大升級 - 從混亂到規范的技術重構之路本文是海貍IM AI創作系列的第18篇文章&#xff0c;記錄7月11日-13日周末期間對移動端的UI統一升級工作。這次重構不是功能性的&#xff0c;而是架構性的 - 我們重新設計了整個UI架構&#x…

八、nginx搭建,實現vue跳轉nginx跳轉gateway

基本的調用鏈路: vue調用nginx,nginx反向代理gateway,gateway看用戶是否登錄,沒有登錄的話,就創建驗證碼并先輸入密碼后獲取token。 截止現在我們創建了兩個項目能夠通過feign調用,并且創建好了gateway,且能調用對應的項目。 這一章節,我們搭建好nginx,通過反向代理,…

C++ 中常見的字符串定義方式及其用法

引言 最近在學習C&#xff0c;下面將從基礎到進階的順序&#xff0c;列出一些 C 中常見的字符串定義方式及其用法&#xff0c;包含完整代碼和詳細注釋&#xff0c;加深對代碼的理解。 C 風格字符串&#xff08;char*或 char[]&#xff09; 定義方式 #include <iostream>i…

下一代防火墻-防范DOS攻擊、IPS防護、web防護實驗

一、實驗拓撲二、實驗設備1.山石網科系列下一代防火墻2.三層交換機一臺3.windows兩臺4.各種工具&#xff0c;如hyenae、小旋風服務器、永恒之藍等等三、實驗目的1.掌握網絡攻擊防護策略配置2.通過下一代防火墻來防護服務器免受DOS攻擊四、防范Dos攻擊實驗1.將一臺windows配置為…

【人工智能】通過 Dify 構建智能助手

通過 Dify 構建智能助手1.定義2.如何使用智能助手3.添加助手需要的工具4.配置 Agent5.配置對話開場白6.添加文件上傳7.調試與預覽8.應用發布1.定義 智能助手&#xff08;Agent Assistant&#xff09;&#xff0c;利用大語言模型的推理能力&#xff0c;能夠自主對復雜的人類任務…

破局與重構:文心大模型開源的產業變革密碼

——從技術壟斷到生態共享的戰略轉型深度解析 引言&#xff1a;一場靜悄悄的革命 2024年&#xff0c;當百度宣布文心大模型4.5系列全面開源時&#xff0c;這不僅僅是一次技術發布&#xff0c;更是一場關于AI產業未來走向的戰略博弈。在全球AI競爭白熱化的當下&#xff0c;開源意…