0

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
    }

}
4

1 回答 1

0

您仍然没有显示相关代码。你在抱怨

if let index = transmitterList.transmitters.firstIndex(of: transmitter)

失败了,但是您没有显示该行在代码中出现的位置,也没有告诉我们是什么transmittertransmitterList.

但是,您已经展示了足够多的信息,可以进行猜测。您已经重新定义了 Transmitter 的相等性,使得两个 Transmitter 当且仅当它们的id值相等时才相等。

static func == (lhs: Transmitter, rhs: Transmitter) -> Bool {
    return lhs.id == rhs.id
}

因此,我们可以得出以下结论:

if let index = transmitterList.transmitters.firstIndex(of: transmitter)

...您的发射器与列表中的任何发射器transmitter不同id。如果这是一个新的,这将是有意义的transmitter,因为它将生成一个新的id

事实上,你说:

我能够通过比较一些发射器属性并以这种方式删除它们来创建一个解决方法,但它似乎不是很健壮

确实没有。但这表明您似乎期望一个 Transmitter 基于“其某些属性”与另一个 Transmitter 等同。它不是。您唯一的平等点是id. 因此,我们可以得出结论,您正在尝试在其他发射器列表中找到transmitter具有唯一id性的 a — 当然它不存在,因为id根据定义,唯一性是唯一的。

于 2019-11-23T20:39:59.207 回答