ios - Swift 在 setter 中检测数组中的哪个对象被更改
问题描述
我有一个习惯对象数组,我正在内存中修改它们,还有一个 getter/setter 用于在进行更改时将其作为 JSON 读取和写入文档存储。我已将每个对象拆分为自己的 JSON 文件,到目前为止一切正常,但是更改数组中的一个对象将重写所有文件。我知道这是我指示我的二传手做的,但是有没有办法只写newValue
那些被改变的对象?
extension Storage {
static var habits: [Habit] {
get { ... }
set {
newValue.forEach({
let data = try! JSONEncoder().encode($0)
do { try data.write(to: Storage.habitsFolder.appendingPathComponent("habit-\($0.id).json")) }
catch let error {
print("Failed to write Habit \($0.id): \(error.localizedDescription)")
}
})
}
}
}
我现在做出改变的方式是Storage.habits[0].name = "Some name"
. 它调用 setter,然后为每个习惯重写文件。所以我想知道是否有某种方法可以检测 newValue 的哪一部分发生了变化或将索引传递给它并且只更新该文件。
解决这个问题的唯一方法是让数组只获取并使用不同的方法来设置每个习惯文件吗?
谢谢,如果这是一个愚蠢的问题,我们深表歉意。
更新:添加习惯类以获得更多上下文
class Habit: Codable, CustomStringConvertible {
// MARK: - Properties
var id: Int
var name: String?
var notes: String?
var icon: String
var repeatPattern: RepeatPattern
var entries: [HabitEntry]
var reminders: [Reminder]
init(id: Int, name: String?, notes: String?, icon: String, entries: [HabitEntry], reminders: [Reminder]) {
self.id = id
self.name = name
self.notes = notes
self.icon = icon
self.repeatPattern = RepeatPattern(pattern: 0, startDay: calendar.today, enabledWeekdays: [1,2,3,4,5,6,7], expectedTimes: 1)
self.entries = entries
self.reminders = reminders
}
var description: String { return "Habit id: \(id), named: \(name ?? "nil"), \nnotes: \(notes ?? "nil"), \nicon: \(icon), \nrepeatPattern: \(repeatPattern), \nentries: \(entries), \nreminders: \(String(describing: reminders))" }
}
解决方案
您可以创建一个属性来存储现有的habits
第一个
class Storage {
static var existingHabits = [Habit]()
}
然后,在 里面set
,看看哪些Habit
是新的:
static var habits: [Habit] {
get { ... }
set {
var habitsToChange = [Habit]()
if existingHabits.count == 0 { /// it's empty, just write with newValue
habitsToChange = newValue
} else {
let differentIndicies = zip(existingHabits, newValue).enumerated().filter() {
$1.0 != $1.1
}.map{$0.0} /// from https://stackoverflow.com/a/30685226/14351818
for index in differentIndicies {
habitsToChange.append(newValue[index])
}
}
habitsToChange.forEach({ /// loop over the habits that have changed
do {
try JSONEncoder().encode($0).write(to: habitsFolder.appendingPathComponent("habit-\($0.id).json"))
} catch {
print("Failed to write Habit \($0.id): \(error)")
}
})
existingHabits = newValue /// set existing to the new value
}
}