我正在創建應用程序,我需要最近的10個搜索列表並保存它(以顯示應用程序啓動之間的一致信息)。NSUserDefaults和我自己的鏈表實現
爲了我已經創建了我的鏈接列表(LinkedList和Node類)的實現和某種包裝類,它將它保持爲最近10個字符串的列表。我讓所有這三個類都符合NSCoding協議,並且在將它保存爲NSUserDefaults時它可以工作。不幸的是,當我嘗試加載它,應用程序錯誤崩潰:
Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (_TtGC26Informacje_o_organizacjach4NodeSS_) for key (head); the class may be defined in source code or a library that is not linked'
這是所有3類的代碼:
類節點
public class Node<T>: NSObject, NSCoding {
var value: T
var next: Node<T>?
var previous: Node<T>?
init(value: T) {
self.value = value
}
public required init(coder aDecoder: NSCoder) {
value = aDecoder.decodeObject(forKey: "value") as! T
next = aDecoder.decodeObject(forKey: "next") as? Node<T>
previous = aDecoder.decodeObject(forKey: "previous") as? Node<T>
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(value, forKey: "value")
aCoder.encode(next, forKey: "next")
aCoder.encode(previous, forKey: "previous")
}
}
LinkedList類
public class LinkedList<T>: NSObject, NSCoding {
fileprivate var head: Node<T>?
private var tail: Node<T>?
override init() {
head = nil
tail = nil
}
public var isEmpty: Bool {
return head == nil
}
public var first: Node<T>? {
return head
}
public var last: Node<T>? {
return tail
}
public var count: Int {
var node = head
var count = 0
while node != nil {
count = count + 1
node = node?.next
}
return count
}
public func removeLast() {
if let lastNode = last {
remove(node: lastNode)
}
}
public func appendFirst(value: T) {
let newNode = Node(value: value)
if let headNode = head {
headNode.previous = newNode
newNode.next = headNode
} else {
tail = newNode
}
head = newNode
}
public func append(value: T) {
let newNode = Node(value: value)
if let tailNode = tail {
newNode.previous = tailNode
tailNode.next = newNode
} else {
head = newNode
}
tail = newNode
}
public func nodeAt(index: Int) -> Node<T>? {
if index >= 0 {
var node = head
var i = index
while node != nil {
if i == 0 { return node }
i -= 1
node = node!.next
}
}
return nil
}
public func removeAll() {
head = nil
tail = nil
}
public func remove(node: Node<T>) -> T {
let prev = node.previous
let next = node.next
if let prev = prev {
prev.next = next
} else {
head = next
}
next?.previous = prev
if next == nil {
tail = prev
}
node.previous = nil
node.next = nil
return node.value
}
public required init?(coder aDecoder: NSCoder) {
head = aDecoder.decodeObject(forKey: "head") as? Node<T>
tail = aDecoder.decodeObject(forKey: "tail") as? Node<T>
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(head, forKey: "head")
aCoder.encode(tail, forKey: "tail")
}
}
個類近期]
public class Recents: NSObject, NSCoding {
fileprivate var list: LinkedList<String>
override init() {
list = LinkedList<String>()
}
public func enqueue(_ element: String) {
if let node = search(for: element) {
list.remove(node: node)
} else {
if list.count >= 10 {
list.removeLast()
}
}
list.appendFirst(value: element)
}
func search(for value: String) -> Node<String>? {
var curr = list.first
while curr != nil {
if curr?.value == value {
return curr
}
curr = curr?.next
}
return nil
}
public func count() -> Int {
return list.count
}
public func nodeAt(index: Int) -> String {
return list.nodeAt(index: index)!.value
}
public var isEmpty: Bool {
return list.isEmpty
}
public required init(coder aDecoder: NSCoder) {
list = aDecoder.decodeObject(forKey: "list") as! LinkedList<String>
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(list, forKey: "list")
}
}
I use this code to load and save data into NSUserDefaults:
func saveRecents() {
let savedData = NSKeyedArchiver.archivedData(withRootObject: recents)
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "recents")
}
func loadRecents() {
let defaults = UserDefaults.standard
if let savedRecents = defaults.object(forKey: "recents") as? Data {
recents = NSKeyedUnarchiver.unarchiveObject(with: savedRecents) as! Recents
}
}
在哪裏的問題?
爲什麼不直接使用數組? – nathan