【发布时间】:2020-03-29 12:22:55
【问题描述】:
我正在关注100 Days of SwiftUI 并已到达Day 37。在做Making changes permanent with UserDefaults的时候,遇到didSet的问题。
(我在 iOS 13.4 中使用 Swift 5)
在示例代码中,它写道
.navigationBarItems(trailing: Button("Save") {
if let actualAmount = Int(self.amount) {
let item = ExpenseItem(name: self.name, type: self.type, amount: actualAmount)
self.expenses.items.append(item)
}
})
didSet 应由 .append() 调用。
然而,在实践中,didSet 不会被调用,除非我将上面的代码更改为
.navigationBarItems(trailing: Button("Save") {
if let actualAmount = Int(self.amount) {
let item = ExpenseItem(name: self.name, type: self.type, amount: actualAmount)
let newItems = self.expenses.items + [item]
self.expenses.items = newItems
}
})
我还在 Playground 中编写了一个小测试(见下文),它表明 .append() 与 didSet 配合得很好
struct Count {
var array: [Int] {
didSet {
print("struct Count - didSet() called")
}
}
}
class CountClass {
var array: [Int] {
didSet {
print("class CountClass - didSet() called")
}
}
init() {
array = [1, 2, 3]
}
}
struct Test {
var countA = Count(array: [1, 2, 3])
var countB = CountClass()
mutating func testDidSet() {
countA.array.append(4)
countB.array.append(4)
}
}
var t = Test()
t.testDidSet()
这种奇怪的行为真的让我想知道didSet 是如何工作的。还是这个问题与@ObservedObject的使用有关(示例项目就是这种情况)?
PS:我从Project7下载了汉化版,也有问题。
【问题讨论】:
-
状态或发布的属性包装器使用“将设置”行为。
-
@Chris 它不是重复的,尽管我同意这是对 SwiftUI 工作原理的相同误解。
-
@user3441734 我将
didSet更改为willSet,仍然无法正常工作......我还尝试将整个ExpenseItem和Expenses更改为一个虚拟的Int值包裹在另一个虚拟类,它适用于=。这真的让我想知道didSet和willSet是否只适用于=...叹息... -
不要走错路!您已经使用过 willSet 和 didSet 属性观察器。使用 ObservedObject 属性包装器没有“奇怪的行为”或一些“相关的问题”。尽量避免混合不同的策略(至少在开始时)并遵循一些 Apple 教程。 SwiftUI 是一个新概念,一个新范式。大多数麻烦(即使是经验丰富的 swift 程序员也可能经常遇到)是缺少文档
标签: swift append swiftui didset