Z
ZHANK
现代 Swift

属性包装器

@propertyWrapper、@State/@Binding(SwiftUI)、@Published、自定义包装器

属性包装器

@propertyWrapper 把属性的存取逻辑封装——@State/@Binding(SwiftUI)、@Published(Combine)都是包装器。

学完本章你将: 掌握 @propertyWrapper、常见系统包装器、自定义包装器。


自定义属性包装器

swift
@propertyWrapper
struct Clamped<T: Comparable> {
    private var value: T
    let range: ClosedRange<T>

    init(wrappedValue: T, _ range: ClosedRange<T>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }

    var wrappedValue: T {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
}

struct Player {
    @Clamped(wrappedValue: 50, 0...100) var health: Int
}

var player = Player()
player.health = 150
print(player.health)  // 100——被限制在范围内

常见系统包装器

swift
// SwiftUI
@State private var count = 0       // 视图本地状态
@Binding var isPresented: Bool     // 从父视图传入
@Environment(\.colorScheme) var scheme  // 环境值
@AppStorage("token") var token = ""     // UserDefaults

// Combine
@Published var users: [User] = []  // 发布变化

// Foundation
@PropertyWrapper
struct UserDefaultsBacked<T> {
    let key: String
    var wrappedValue: T? { ... }
}