我正在尝试使用NSUserDefaults将数组保存到我的应用程序的核心数据中。我认为使用NSUserDefaults会很好,但是问题是,无论我将创建默认代码的代码放在哪里,都会引发SIGABRT错误。
这是创建默认值的代码:
let levelArrayDefault = NSUserDefaults.standardUserDefaults() levelArrayDefault.setValue(levelsArray, forKey: "levelsArray") levelArrayDefault.synchronize()
levelsArray是List对象的数组:
class List: NSObject, NSCoding { // MARK: Properties var name: String var AnswersArray = [Answer]() init?(name: String) { // Initialize stored properties. self.name = name if name.isEmpty { return nil } } required init(coder decoder: NSCoder){ self.AnswersArray = (decoder.decodeObjectForKey("AA") as? [Answer])! self.name = (decoder.decodeObjectForKey("name") as? String)! } func encodeWithCoder(coder: NSCoder) { if let AnswersArray = AnswersArray { coder.encodeObject(AnswersArray, forKey: "AA") } if let name = name { coder.encodeObject(name, forKey: "name") } } } class Answer: NSObject, NSCoding { var EnglishAnswer: String = "" var ChineseAnswer: String = "" init(newEng: String, newChi: String){ self.EnglishAnswer = newEng self.ChineseAnswer = newChi } required init(coder decoder: NSCoder){ self.EnglishAnswer = (decoder.decodeObjectForKey("EnglishAnswer") as? String)! self.ChineseAnswer = (decoder.decodeObjectForKey("ChineseAnswer") as? String)! } func encodeWithCoder(coder: NSCoder) { if let EnglishAnswer = EnglishAnswer { coder.encodeObject(EnglishAnswer, forKey: "EnglishAnswer") } if let ChineseAnswer = ChineseAnswer { coder.encodeObject(ChineseAnswer, forKey: "ChineseAnswer") } } }
如何阻止SIGABRT弹出并存储阵列。帮助将不胜感激。
您需要先使用NSKeyedArchiver将其转换为NSData,然后再将其存储到NSUserDefaults中,如下所示:
更新:Xcode 8.2.1•Swift 3.0.2
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let list = List(name: "Student") list.answers = [Answer(english: "english answer", chinese: "中文回答")] let data = NSKeyedArchiver.archivedData(withRootObject: [list]) UserDefaults.standard.set(data, forKey: "listData") guard let loadedData = UserDefaults.standard.data(forKey: "listData"), let loadedArray = NSKeyedUnarchiver.unarchiveObject(with: loadedData) as? [List] else { return } print(loadedData.count) print(loadedArray.first ?? "none") print(loadedArray.first?.name ?? "no name") print(loadedArray.first?.answers.first?.english ?? "no english") print(loadedArray.first?.answers.first?.chinese ?? "no chinese") } }
class Answer: NSObject, NSCoding { let english: String let chinese: String init(english: String, chinese: String) { self.english = english self.chinese = chinese } required init(coder decoder: NSCoder) { self.english = decoder.decodeString(forKey: "english") self.chinese = decoder.decodeString(forKey: "chinese") } func encode(with coder: NSCoder) { coder.encode(english, forKey: "english") coder.encode(chinese, forKey: "chinese") } }
class List: NSObject, NSCoding { let name: String fileprivate var data = Data() var answers: [Answer] { get { return NSKeyedUnarchiver.unarchiveObject(with: data) as? [Answer] ?? [] } set { data = NSKeyedArchiver.archivedData(withRootObject: newValue) } } init(name: String) { self.name = name } required init(coder decoder: NSCoder) { self.data = decoder.decodeData(forKey: "answersData") self.name = decoder.decodeString(forKey: "name") } func encode(with coder: NSCoder) { coder.encode(data, forKey: "answersData") coder.encode(name, forKey: "name") } }
extension NSCoder { func decodeString(forKey key: String) -> String { return decodeObject(forKey: key) as? String ?? "" } func decodeData(forKey key: String) -> Data { return decodeObject(forKey: key) as? Data ?? Data() } }