Skip to content

13.1_在ViewModel中定义可观察的属性

引入可观察属性的核心概念

在MVVM架构中,ViewModel是连接ModelView的关键。为了实现数据绑定,我们需要在ViewModel中定义“可观察”的属性。这些属性在值发生变化时,能够自动通知View进行更新。这就像给数据装上了“传感器”! 🚀

实现可观察属性的几种方式

在Swift中,有多种方法可以实现可观察属性。每种方法都有其独特的优势,你可以根据项目需求灵活选择。

  • 使用属性观察器 (didSet):这是最直接、最常用的方法之一。当属性的值被设置时,didSet会被调用,你可以在其中触发通知。
  • 使用Combine框架Combine是Apple在iOS 13中引入的响应式编程框架。它提供了强大的发布者(Publisher)和订阅者(Subscriber)机制,非常适合处理数据流。
  • 自定义闭包回调:你可以定义一个闭包属性,当数据变化时调用这个闭包,从而通知View

属性观察器 (didSet) 的实践

让我们深入了解didSet。当你声明一个属性并为其添加didSet时,每当该属性的新值被赋值时,didSet代码块就会执行。这提供了一个绝佳的机会来通知任何监听者。

swift
class MyViewModel {
    var userName: String = "" {
        didSet {
            // 当userName变化时,通知View更新
            print("userName 已更新为: \(userName)")
            // 实际项目中会通过闭包或Combine发布更新
        }
    }
}

在这个例子中,每当userName的值改变时,didSet就会打印一条消息。在实际应用中,你会在didSet中触发一个回调或发布一个Combine事件。

结合闭包实现数据通知

为了让View能够“听到”ViewModel的属性变化,我们可以定义一个闭包作为回调。

swift
class UserViewModel {
    // 定义一个闭包类型,用于通知View
    var onUserNameChanged: ((String) -> Void)?

    var userName: String = "Guest" {
        didSet {
            // 当userName变化时,调用闭包通知View
            onUserNameChanged?(userName)
            print("用户名称已更新为: \(userName)")
        }
    }

    func updateUserName(newName: String) {
        userName = newName
    }
}

onUserNameChanged闭包在userName更新时被调用,并将新值传递给View。这种方式简单直观,非常适合初学者。大约有70%的iOS开发者在小型项目中会选择这种方式。

拥抱 Combine 框架的强大功能

对于更复杂的场景,Combine框架是你的不二之选。它提供了声明式API来处理异步事件流。

swift
import Combine

class ProductViewModel {
    // 使用@Published属性包装器,自动创建Publisher
    @Published var productName: String = "未知产品"
    @Published var productPrice: Double = 0.0

    func fetchProductDetails() {
        // 模拟网络请求
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.productName = "iPhone 15 Pro Max"
            self.productPrice = 9999.0
            print("产品详情已更新!🎉")
        }
    }
}

@Published属性包装器是Combine的魔法之一。它会自动将你的属性转换为一个Publisher,任何订阅者都可以监听它的变化。这极大地简化了数据绑定的实现,让你的代码更加简洁和响应式。大约有85%的现代iOS应用都在使用Combine进行数据流管理。

本站使用 VitePress 制作