结构体、类与协议
struct/class、Protocol、ARC。
35 分钟
结构体、类与协议
Swift 是协议导向语言:struct 值类型用于模型,class 引用类型用于共享状态,protocol 定义能力契约。对照 /roadmaps/swift-ui「OOP」节点,这是 SwiftUI 数据建模与 ViewModel 的基础。
学习目标
- 区分 struct 与 class 的语义与拷贝行为
- 使用 protocol 与 extension 组织代码
- 理解 ARC 与
weak/unowned打破循环引用 - 为 SwiftUI 模型实现
Identifiable、Codable
核心概念
struct vs class
struct Lesson: Identifiable, Codable, Equatable {
let id: Int
var title: String
var completed: Bool
}
// 值类型:拷贝独立
var a = Lesson(id: 1, title: "语法", completed: false)
var b = a
b.completed = true
print(a.completed) // false,a 不受影响
// 引用类型:共享实例
class LessonStore {
var lessons: [Lesson] = []
func markComplete(id: Int) {
if let i = lessons.firstIndex(where: { $0.id == id }) {
lessons[i].completed = true
}
}
}
let store1 = LessonStore()
let store2 = store1 // 同一实例
store2.lessons.append(Lesson(id: 1, title: "OOP", completed: false))
print(store1.lessons.count) // 1
SwiftUI 模型优先 struct(线程安全、可预测);ViewModel 用 class + ObservableObject。
Protocol 与 Extension
protocol TrackDisplayable {
var displayTitle: String { get }
var lessonCount: Int { get }
}
struct Track: TrackDisplayable, Identifiable {
let id: Int
var title: String
var lessons: [Lesson]
var displayTitle: String { "📚 \(title)" }
var lessonCount: Int { lessons.count }
}
extension Track {
var completionRate: Double {
guard !lessons.isEmpty else { return 0 }
let done = lessons.filter(\.completed).count
return Double(done) / Double(lessons.count)
}
}
Protocol 支持组合能力;Extension 为已有类型添加计算属性与方法,无需继承。
ARC 与 weak
class NetworkManager {
var onComplete: (() -> Void)?
func fetch(completion: @escaping () -> Void) {
onComplete = completion
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
completion()
}
}
}
// 闭包捕获 self 时用 weak 避免循环引用
class LessonViewModel: ObservableObject {
private let manager = NetworkManager()
func load() {
manager.fetch { [weak self] in
self?.refreshUI()
}
}
private func refreshUI() { /* 更新 @Published */ }
}