从plist加载后,对象似乎不符合Equatable
协议的问题。背景知识:我有一个对象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)")
}
}
}
}
添加Transmitter类。任何其他类型也都符合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
}
}