encodeWithCoder: нераспознанный селектор, отправленный экземпляру

Я пытаюсь использовать протокол NSCoding для чтения и записи данных в plist. Я получаю исключение, когда пытаюсь написать [GolfHoles], который является подклассом NSObject. Я прочитал несколько постов с разными подходами, но ни один не помог.

class GolfCourse: NSObject, NSCoding {
var name: String = ""
var location: String = ""
var holes: [GolfHole] = [GolfHole]()

init(holes: [GolfHole]) {
    self.holes = holes
}

// MARK: NSCoding Protocol
func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(name, forKey: "name")
    aCoder.encodeObject(location, forKey: "location")
    aCoder.encodeObject(holes, forKey: "holes") // exception here

}

required init(coder aDecoder: NSCoder) {
    super.init()
    name = aDecoder.decodeObjectForKey("name") as! String
    location = aDecoder.decodeObjectForKey("location") as! String
    holes = aDecoder.decodeObjectForKey("holes") as! [GolfHole]

}

override init() {
    super.init()
    for var i=0; i<18; i++ {
        let newHole = GolfHole()
        self.holes.append(newHole)

    }
}

}

Как мне написать и прочитать массив?

1 ответ

Рмадди прав. Вы должны иметь все свои классы, которые будут сохранены, чтобы также соответствовать NSCoding. Итак, вот тривиальный пример класса GolfHole и как сериализовать объект GolfCourse.

class GolfHole: NSObject, NSCoding {
  let number: Int
  let par: Int

  init(number: Int, par: Int) {
    self.number = number
    self.par = par
  }

  convenience required init?(coder aDecoder: NSCoder) {
    guard
      let number = aDecoder.decodeObjectForKey("number") as? Int,
      let par    = aDecoder.decodeObjectForKey("par")    as? Int
    else {
      return nil
    }
    self.init(number: number, par: par)
  }

  func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(number, forKey: "number")
    aCoder.encodeObject(par,    forKey: "par")
  }
}


class GolfCourse: NSObject, NSCoding {
  var name = ""
  var location = ""
  var holes = [GolfHole]()

  init(name: String, location: String, holes: [GolfHole]) {
    self.name = name
    self.location = location
    self.holes = holes
  }

  convenience required init?(coder aDecoder: NSCoder) {
    guard
      let name     = aDecoder.decodeObjectForKey("name")     as? String,
      let location = aDecoder.decodeObjectForKey("location") as? String,
      let holes    = aDecoder.decodeObjectForKey("holes")    as? [GolfHole]
    else {
      return nil
    }
    self.init(name: name, location: location, holes: holes)
  }

  func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(name,     forKey: "name")
    aCoder.encodeObject(location, forKey: "location")
    aCoder.encodeObject(holes,    forKey: "holes")
  }
}

введите описание изображения здесь

Другие вопросы по тегам