Redux 是前端領域經典的狀態管理模式,核心遵循單向數據流不可變狀態原則,在 iOS 開發中,可通過原生 Swift 實現 Redux 架構思想,也可藉助第三方庫(如ReSwift)快速落地,適用於複雜應用的全局狀態管理(如用户信息、主題設置、多頁面共享數據等場景)。以下從核心概念、實現方式、實戰案例展開解析:

一、Redux 核心概念(iOS 映射)

Redux 的核心由Store(狀態倉庫)、Action(行為指令)、Reducer(狀態處理器)、Middleware(中間件)四部分組成,在 iOS 中對應關係如下:

Redux 概念

iOS 中的實現形式

作用

Store

單例類(含狀態對象 + 派發方法)

存儲全局唯一狀態,提供dispatch(_ action:)方法觸發狀態更新

Action

枚舉 / 結構體(含typepayload

描述 “發生了什麼”,是修改狀態的唯一指令(如UserAction.login(user:)

Reducer

純函數((State, Action) -> State

根據 Action 類型計算新狀態,不可直接修改原狀態(需返回新對象)

State

結構體(不可變設計)

存儲應用狀態(如AppState(user: User?, theme: Theme)

Middleware

閉包 / 類(攔截dispatch過程)

處理副作用(如網絡請求、日誌記錄),常見於ReSwift等庫

二、iOS 中實現 Redux 的兩種方式

1. 原生 Swift 手動實現 Redux(輕量場景)

通過 Swift 的值類型(Struct)和函數式編程特性,手動構建核心模塊:

步驟 1:定義 State(不可變狀態)

swift

// 應用全局狀態
struct AppState {
    var user: User? // 用户信息
    var todos: [Todo] = [] // 待辦列表
    var theme: Theme = .light // 主題設置
}

// 子狀態(按需拆分)
struct User {
    let id: String
    let name: String
    let token: String
}

enum Theme {
    case light, dark
}
步驟 2:定義 Action(行為指令)

swift

// 全局Action枚舉(按功能拆分)
enum AppAction {
    // 用户相關
    case login(User)
    case logout
    // 待辦相關
    case addTodo(Todo)
    case deleteTodo(id: String)
    // 主題相關
    case switchTheme(Theme)
}
步驟 3:實現 Reducer(狀態計算)

swift

// 純函數:接收舊狀態+Action,返回新狀態
func appReducer(state: AppState, action: AppAction) -> AppState {
    var newState = state // 基於舊狀態創建新狀態(不可變)
    switch action {
    case .login(let user):
        newState.user = user
    case .logout:
        newState.user = nil
    case .addTodo(let todo):
        newState.todos.append(todo)
    case .deleteTodo(let id):
        newState.todos.removeAll { $0.id == id }
    case .switchTheme(let theme):
        newState.theme = theme
    }
    return newState
}
步驟 4:實現 Store(狀態倉庫,單例)

swift

final class Store {
    static let shared = Store() // 全局單例
    private(set) var state: AppState // 私有狀態,僅通過dispatch修改
    
    private init() {
        state = AppState() // 初始狀態
    }
    
    // 派發Action,觸發狀態更新
    func dispatch(action: AppAction) {
        state = appReducer(state: state, action: action)
        // 通知訂閲者狀態變化(如用NotificationCenter或Combine)
        NotificationCenter.default.post(name: .stateDidChange, object: nil)
    }
}
步驟 5:頁面訂閲與觸發 Action

swift

// 登錄頁面:觸發Action
class LoginViewController: UIViewController {
    func loginSuccess(user: User) {
        Store.shared.dispatch(action: .login(user))
    }
}

// 個人中心頁面:訂閲狀態變化
class ProfileViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(updateUI),
            name: .stateDidChange,
            object: nil
        )
    }
    
    @objc private func updateUI() {
        let user = Store.shared.state.user
        userNameLabel.text = user?.name ?? "未登錄"
    }
}

2. 基於第三方庫 ReSwift(複雜場景)

ReSwift是 iOS 端成熟的 Redux 實現庫,封裝了 Store、Middleware、Subscriber 等機制,無需手動處理狀態訂閲和線程安全:

步驟 1:集成 ReSwift

swift

// Podfile
pod 'ReSwift'
步驟 2:定義 State 和 Action

swift

import ReSwift

struct AppState: StateType {
    var user: User?
    var todos: [Todo] = []
}

enum AppAction: Action {
    case login(User)
    case logout
    case addTodo(Todo)
}
步驟 3:實現 Reducer

swift

func appReducer(action: Action, state: AppState?) -> AppState {
    let state = state ?? AppState()
    guard let action = action as? AppAction else { return state }
    
    switch action {
    case .login(let user):
        return AppState(user: user, todos: state.todos)
    case .logout:
        return AppState(user: nil, todos: state.todos)
    case .addTodo(let todo):
        var todos = state.todos
        todos.append(todo)
        return AppState(user: state.user, todos: todos)
    }
}
步驟 4:創建 Store 並訂閲

swift

// 全局Store
let store = Store(
    reducer: appReducer,
    state: nil,
    middleware: [loggingMiddleware] // 可選:中間件(如日誌)
)

// 頁面訂閲狀態
class TodoListViewController: UIViewController, StoreSubscriber {
    typealias StoreSubscriberStateType = AppState
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        store.subscribe(self)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        store.unsubscribe(self)
    }
    
    // 狀態更新回調
    func newState(state: AppState) {
        todoTableView.reloadData(with: state.todos)
    }
    
    // 觸發Action
    func addNewTodo() {
        let todo = Todo(id: "1", title: "學習Redux")
        store.dispatch(AppAction.addTodo(todo))
    }
}
步驟 5:Middleware 處理副作用(如網絡請求)

swift

// 日誌中間件示例
let loggingMiddleware: Middleware<AppState> = { dispatch, getState in
    return { next in
        return { action in
            print("Dispatching action: \(action)")
            next(action) // 傳遞Action給下一個中間件/Reducer
            print("New state: \(getState()!)")
        }
    }
}

// 網絡請求中間件(登錄邏輯)
let authMiddleware: Middleware<AppState> = { dispatch, getState in
    return { next in
        return { action in
            if let loginAction = action as? AppAction, case .login(let user) = loginAction {
                // 模擬網絡請求
                AuthService.login(user: user) { result in
                    switch result {
                    case .success(let token):
                        dispatch(AppAction.saveToken(token)) // 派發後續Action
                    case .failure:
                        dispatch(AppAction.loginFailed)
                    }
                }
            }
            next(action)
        }
    }
}

三、Redux 在 iOS 中的適用場景與優勢

1. 適用場景

  • 全局狀態共享:用户信息、主題設置、多頁面共享的購物車數據等;
  • 複雜狀態流轉:如電商下單流程(選品→結算→支付→訂單)、社交 APP 的消息狀態;
  • 可回溯 / 調試需求:通過記錄 Action 日誌,復現用户操作路徑(類似 Redux DevTools)。

2. 核心優勢

  • 單向數據流:狀態變化可預測,便於調試和定位 Bug;
  • 狀態集中管理:避免多頁面傳值混亂(如 Delegate、NotificationCenter 濫用);
  • 不可變狀態:通過值類型(Struct)實現狀態不可變,避免多線程數據競爭;
  • 純函數 Reducer:無副作用,便於單元測試(輸入確定→輸出確定)。

四、iOS 中 Redux 的侷限性與替代方案

1. 侷限性

  • 樣板代碼較多:Action、Reducer 等定義增加代碼量,簡單場景(如單頁面狀態)顯得冗餘;
  • SwiftUI 適配:SwiftUI 本身通過@State/@ObservableObject實現狀態管理,Redux 可作為補充但非必需;
  • 性能考量:全局狀態更新可能觸發無關頁面刷新(需優化訂閲邏輯)。

2. 替代方案

  • SwiftUI 原生狀態管理@State/@StateObject/@EnvironmentObject(輕量場景);
  • Combine+MVVM:通過PassthroughSubject/CurrentValueSubject實現狀態流轉;
  • TCA(The Composable Architecture):更貼合 Swift 的函數式狀態管理庫,融合 Redux 思想 + Swift 特性。

五、總結

Redux 並非 iOS 原生模式,但其 “單向數據流 + 不可變狀態” 的思想可有效解決複雜應用的狀態管理問題。在 iOS 開發中,可根據項目複雜度選擇原生手動實現(輕量需求)或ReSwift/TCA(複雜場景),核心是通過 “Action 驅動狀態變化” 讓代碼更可預測、可維護。對於簡單 APP,優先使用系統原生狀態管理;對於大型應用,Redux 是優化狀態混亂的優質選擇。