NSKeyedUnarchiver EXC_BAD_INSTRUCTION с протоколом

Я обновляю свое приложение для поддержки версий IOS 11. В настоящее время оно работает на IOS 13.2. Но на IOS 11 и IOS 12.2 у меня есть EXC_BAD_INSTRUCTION в NSKeyedUnarchiver decodeObject.

Класс с ошибкой

class Seance : NSObject, NSCoding{
  var date: NSDate
  var action: [String:ObjectifData] = Seance.actionStartupPoint()
  var duration = 0.0
  static var instance: Seance? = nil

static func actionStartupPoint() -> [String: ObjectifData]{
    var a: [String: ObjectifData] = [String:ObjectifData]()
    for objectif in Storage.instance.objectif{
        a[objectif.key] = objectif.value.type.initialise
    }
    return a;
}


init(date: NSDate){
    self.date = date;
}

required init(coder decoder: NSCoder){
    self.date = decoder.decodeObject(forKey: "date") as! NSDate
    self.action = try decoder.decodeObject(forKey: "action") as! [String: ObjectifData] // EXC_BAD_INSTRUCTION ERROR
    self.duration = decoder.decodeDouble(forKey: "duration")
}
func encode(with coder: NSCoder){
    print(action)
            print(date)
                    print(duration)
    coder.encode(date, forKey: "date")
    coder.encode(action, forKey: "action")
    coder.encode(duration, forKey: "duration")
}

func convertActionToObjectifData() -> [String: Objectif]{
    var dic: [String: Objectif] = [:]
    for convert in action{
        if Storage.instance.objectif[convert.key] != nil {
            dic[convert.key] = Storage.instance.objectif[convert.key]!
        }
    }
    return dic
}
}

ObjectifData - это протокол с 3 родителями

Нравится

class BinaireData : NSObject, NSCoding, ObjectifData {

var validate: Bool = false

func encode(with coder: NSCoder) {
    coder.encode(validate, forKey: "validate")
}
override init(){}
required init(coder decoder: NSCoder) {
    super.init()
    self.validate = decoder.decodeBool(forKey: "validate")
}


func getObjectifType() -> ObjectifType {
    return .binaire
}

func getPrimaryValue() -> Double {
    return validate ? 1 : 0
}

func stringFormatedValue() -> String {
    return validate ? "Oui" : "Non"
}
func updateFromWatch(message: [String : Any]) -> Bool {
    let value: Bool = message["event"] as! Bool
    if(self.validate != value){
        self.validate = value
        return true
    }
    return false
}
}

ObjectifData =

protocol ObjectifData: NSObject {

func getObjectifType() -> ObjectifType
func getPrimaryValue() -> Double
func stringFormatedValue() -> String
func updateFromWatch(message: [String:Any]) -> Bool}

И для загрузки это делаю при запуске

training = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String: [Seance]]

Трассировка стека точки останова

после нескольких исследований я заметил, что, возможно, проблема возникает из-за протоколов, которые не разрешены в NSKeyUnarchiver на ios11

это правда? Как я могу решить проблему? Спасибо за чтение хорошего дня

2 ответа

Решение

Вы пытаетесь кодировать и декодировать объект, набранный как [String: ObjectifData], где ObjectifData - протокол. Вы не можете этого сделать; протокол не настоящего типа! Я не удивлен крушением; Я только удивлен, что это не дает сбоев и в iOS 13.

Чтобы иметь возможность кодировать классы, которые принимают ObjectifData он также должен быть ограничен NSCoding

protocol ObjectifData: NSObject, NSCoding
Другие вопросы по тегам