Các property wrapper này đều cho SwiftUI biết và . Ranh giới chính là (, ) so với (, , ), cộng thêm ai chịu trách nhiệm về vòng đời của object.
@State@Binding@StateObject@ObservedObject@EnvironmentObject// State kiểu value do CHÍNH view này sở hữu
struct Toggle: View {
@State private var isOn = false // nguồn chân lý cục bộ
var body: some View {
Switch(isOn: $isOn) // $ tạo ra một Binding
}
}
// Tham chiếu hai chiều tới state do NƠI KHÁC sở hữu
struct Switch: View {
@Binding var isOn: Bool // không sở hữu; đọc+ghi của cha
var body: some View { Button("\(isOn)") { isOn.toggle() } }
}
final class CartModel: ObservableObject {
@Published var items: [Item] = [] // đổi => các view re-render
}
struct CartScreen: View {
@StateObject private var model = CartModel() // SỞ HỮU: tạo một lần, sống qua re-render
var body: some View { CartList(model: model) }
}
struct CartList: View {
@ObservedObject var model: CartModel // quan sát; do cha sở hữu
var body: some View { Text("\(model.items.count)") }
}
| Wrapper | Kiểu | Sở hữu | Dùng khi |
|---|---|---|---|
@State | value | chính view này | state cục bộ đơn giản |
@Binding | value | một view cha | con sửa state của cha |
@StateObject | reference | chính view này (tạo một lần) | view tạo ra model |
@ObservedObject | reference | nơi khác | model được truyền vào |
@EnvironmentObject | reference | tổ tiên | dùng chung sâu trong cây |
@StateObject vs @ObservedObject là bẫy kinh điển. Tạo model bằng @ObservedObject var m = Model() sẽ khởi tạo lại nó mỗi lần re-render, âm thầm mất state. Hãy dùng @StateObject ở nơi view tạo ra object.@EnvironmentObject crash lúc chạy nếu không có tổ tiên nào inject nó qua .environmentObject(...).Chọn sai wrapper là nguồn lỗi state số một trong SwiftUI — giá trị nhấp nháy, reset khi scroll, hoặc view không bao giờ cập nhật. Người phỏng vấn hỏi câu này vì câu trả lời @StateObject vs @ObservedObject lập tức cho thấy bạn có hiểu mô hình sở hữu của SwiftUI hay không.
Thư viện câu hỏi phỏng vấn IT với đáp án chi tiết — từ Junior đến Senior.
Ủng hộ