Equatable
从 plist 加载后,我遇到的对象似乎不符合协议的问题。一些背景知识:我有一个对象TransmitterList
类型,它包含一个 Transmitters 类型的数组。在第一次启动时,一切正常,我可以通过调用删除项目
if let index = transmitterList.transmitters.firstIndex(of: transmitter) {
transmitterList.transmitters.remove(at: index)
}
此方法在第一次运行时完美运行,问题出现在应用程序数据已保存并在终止应用程序后重新加载之后。所有保存和加载都是使用Codable
协议和 Plist 编码器和解码器完成的。发射器列表中的发射器仍然存在,但是当尝试删除发射器时,调用firstIndex(of:)
返回nil
。其他依赖Equatable
协议的方法也不能正常工作。似乎保存的发射器不再符合Equatable
. 但是,在重新启动后添加新发射器时,我能够成功删除任何新添加的发射器。
我能够通过比较一些发射器属性并以这种方式删除它们来创建一个解决方法,但它似乎不是很健壮。真的想了解发射机不再符合的根本原因Equatable
。
任何帮助表示赞赏,谢谢!
更新了保存和加载代码。
这是我正在使用的 dataModel 对象,它只是保存了一个 TransmitterLists 数组。Transmitter 类中没有自定义编码或解码,它只是符合,Codable
没有任何额外的方法。
class DataModel {
// MARK: - Properties
var transmitterLists = [TransmitterList]()
// MARK: - Initialization
init() {
loadData()
}
// MARK: - Data Persistence
func documentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)
return paths[0]
}
func dataFilePath() -> URL {
return documentsDirectory().appendingPathComponent("FrequencyCoordinator.plist")
}
func saveData() {
let encoder = PropertyListEncoder()
do {
let data = try encoder.encode(transmitterLists)
try data.write(to: dataFilePath(), options: Data.WritingOptions.atomic)
print("DATA SAVED!!")
} catch {
print("That did not work: \(error.localizedDescription)")
}
}
func loadData() {
let path = dataFilePath()
if let data = try? Data(contentsOf: path) {
let decoder = PropertyListDecoder()
do {
print("DATA LOADED")
transmitterLists = try decoder.decode([TransmitterList].self, from: data)
} catch {
print("That didnt work ;-< \(error.localizedDescription)")
}
}
}
}
添加发送器类。任何其他类型也符合Codable
但仅通过在定义中声明。也许在确保类型正确符合方面还有更多工作要做?
class Transmitter: Equatable, Codable {
static func == (lhs: Transmitter, rhs: Transmitter) -> Bool {
return lhs.id == rhs.id
}
var id: Int
var name: String
var transmitterType: TransmitterType
var block: Block
var frequency: Frequency
var doesOverlap: Bool = false
var transmitterOverlapRange: ClosedRange<Double>
var imProductOverlapRanges = [ClosedRange<Double>]()
var overlapsWith = [Transmitter]()
var doesHaveTwoTransmitterIMInterference = false
var doesHaveThreeTransmitterIMInterference = false
var twoTransmitterIMProductsOverlap = [TwoTransmitterIMProduct]()
var threeTransmitterIMProductsOverlap = [ThreeTransmitterIMProduct]()
var isDisabled = false
var frequencyIsSet: Bool {
get {
self.frequency.literal != 0.0
}
}
init(name: String, type: TransmitterType, block: Block, frequency: Frequency, transmitterOverlapRange: ClosedRange<Double>) {
self.id = DataModel.nextTransmitterID()
self.name = name
self.transmitterType = type
self.block = block
self.frequency = frequency
self.transmitterOverlapRange = transmitterOverlapRange
}
enum TransmitterType: Int, Codable {
case talent
case hops
case ifb
}
}