- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
作为面向协议(protocol)的编程概念,我使用Struct 创建了我的模型。
我想将“Struct
”的Array 保存到Userdefault 中。但是我在对这个模型的数组进行编码/解码时遇到了问题。
这是我的模型结构
struct Room {
let name : String
let id : String
let booked : Bool
}
我在这里创建了一个像这样的扩展
extension Room {
func decode() -> Room? {
let userClassObject = NSKeyedUnarchiver.unarchiveObject(withFile: RoomClass.path()) as? RoomClass
return userClassObject?.room
}
func encode() {
let personClassObject = RoomClass(room: self)
NSKeyedArchiver.archiveRootObject(personClassObject, toFile: RoomClass.path())
}
class RoomClass: NSObject, NSCoding {
var room : Room?
init(room: Room) {
self.room = room
super.init()
}
class func path() -> String {
let documentsPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
let path = documentsPath?.appending(("/Room"))
return path!
}
func encode(with aCoder: NSCoder) {
aCoder.encode(room!.name, forKey: "name")
aCoder.encode(room!.id, forKey: "Id")
aCoder.encode(room!.booked, forKey: "booked")
}
required init?(coder aDecoder: NSCoder) {
let _name = aDecoder.decodeObject(forKey: "name") as? String
let _id = aDecoder.decodeObject(forKey: "Id") as? String
let _booked = aDecoder.decodeBool(forKey: "booked")
room = Room(name: _name!, id: _id!, booked: _booked)
super.init()
}
}
}
当我试图像这样保存arrRoomList(房间对象数组)时
self.saveRooms(arrayRooms: arrRoomList)
我遇到了这个错误
[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance
我也试过先对每个对象进行编码,然后尝试将它们保存为默认值,然后它也会报错。
谁能指导我如何以正确的方式编码/解码 Userdefaults 中的结构数组而不将其转换为字典?
最佳答案
您可以像这样设置结构以直接使用 NSKeyedArchiver
:
struct Room {
let name : String
let id : String
let booked : Bool
}
extension Room {
func encode() -> Data {
let data = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWith: data)
archiver.encode(name, forKey: "name")
archiver.encode(id, forKey: "id")
archiver.encode(booked, forKey: "booked")
archiver.finishEncoding()
return data as Data
}
init?(data: Data) {
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
defer {
unarchiver.finishDecoding()
}
guard let name = unarchiver.decodeObject(forKey: "name") as? String else { return nil }
guard let id = unarchiver.decodeObject(forKey: "id") as? String else { return nil }
booked = unarchiver.decodeBool(forKey: "booked")
self.name = name
self.id = id
}
}
要与 UserDefaults 一起使用,请这样调用:
// to encode to data and save to user defaults
let room = Room(name: "asdf", id: "123", booked: true)
UserDefaults.standard.set(room.encode(), forKey: "room")
// to retrieve from user defaults
if let data = UserDefaults.standard.object(forKey: "room") as? Data {
let room = Room(data: data)
}
可以像这样保存/检索房间数组:
func saveRooms(arrayRooms: [Room]) {
let roomsData = arrayRooms.map { $0.encode() }
UserDefaults.standard.set(roomsData, forKey: "rooms")
}
func getRooms() -> [Room]? {
guard let roomsData = UserDefaults.standard.object(forKey: "rooms") as? [Data] else { return nil }
return roomsData.flatMap { return Room(data: $0) }
}
// save 2 rooms to user defaults
let roomA = Room(name: "A", id: "123", booked: true)
let roomB = Room(name: "B", id: "asdf", booked: false)
saveRooms(arrayRooms: [roomA, roomB])
// get the rooms
print(getRooms())
关于ios - 使用 NSKeyedArchiver 和 Userdefault 保存结构数组,其中对象符合 NSCoding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40779910/
假设我有这个 Swift 类: class Foo: NSObject, NSCoding { var stringMember: String var intMember: Int
我需要对包含多个自定义 NSObject 实例的数组进行编码类(class)。但是,这样做时,它会返回带有消息的崩溃: -[Person encodeWithCoder:]: unrecognized
import Foundation class C: NSObject, NSCoding { var n: String = "" override init() {
我正在尝试将 NSCoding 协议(protocol)添加到我的自定义类中: class Convo: NSObject, NSCoding { var name: String v
我有一个 costum 对象,它引用了另一个自定义对象。如何在我的 - (void)encodeWithCoder:(NSCoder *)encoder 方法中对一个自定义对象内的自定义对象进行编码?
我有 .h 和 .m 来实现 NSCoding,但是 mutableArray 对象计数总是 0 ... .h #import @interface Favorite : NSObject {
我有一个自定义对象,我想将其保存到磁盘而不是内存。自定义对象有子对象,子对象有子对象等等。这棵树相当广泛。其中一个子对象有 30 多个属性,其中 6 个是子对象本身。 如果我想使用NSCoding,是
我有两个类:Contact 和 Bill。 Contact 有一个类型为 Bill 的数组。 当我坚持使用 NSKeyedArchiver 时,我的联系人保持得很好,但是,它不会保持 Bill 数组。
我有一个带有 NSString 键和 Class (objc_class) 值的 NSDictionary,我想使用 NSCoding 存档这个字典 协议(protocol)。 我如何存档“类”对象?
当使用 NSCoding 或 NSKeyedArchiver 建立父子关系时;我无法在子项中设置对父项的引用,因为它最终会在 Swift Playground 上崩溃。 我想在我的 Child 类中引
我一辈子都弄不明白为什么我会收到此类不符合 NSCoding 协议(protocol)的错误。也许另一双眼睛会有所帮助。我试图添加注释以明确每个函数在做什么。 import Foundation im
我使我的以下 Person 类符合 NSCoding 协议(protocol)。 class Person: NSObject, NSCoding{ var age:Int var h
我正在尝试能够序列化和解码自定义类。该类本身有一个属性,它是一个枚举数组,如下所示: (我已经阅读了如何使用原始值并将其序列化,但我还没有弄清楚如何使用这样的数组来做到这一点)。 enum WeekD
我有一个带有 String 属性和 NSImage 属性的“Thing”对象; Thing 类有 encodeWithCoder: 和 decodeWithCoder: 方法,我可以使用 NSKeye
我正在使用 NSCoding 来存档/取消存档自定义类作为数据持久化的方法。如果对象是 NSObject 的子类,它工作正常,但我也有对象是自定义对象的子类。我是否需要更改 initWithCoder
我有一系列嵌套对象需要通过 NSCoding 协议(protocol)进行处理,以便我可以将顶级对象保存到 NSUserDefaults 中。 这是对象的结构: '讲师'类 NSMutableArra
-(void)transformObjects:(NSMutableArray*)array key:(NSString*)key { NSMutableArray* archiveArray
我在 Swift 中使用 NSCoding 时遇到问题。我试图实现该协议(protocol),但每当我调用我的 save() 方法时都会发生崩溃。 Xcode 在 encodeWithCoder 中将
我正在尝试使用基本的父子对象继承系统编写一个简单的 RPG,该系统被保存并加载到游戏状态中,但是当发生加载时,父级没有数据出现,我正在努力理解为什么。 为了简单起见,我做了一个简单的父子对象继承,其中
我有一个 NSPopUpButtonCell 的自定义子类,以便我可以覆盖其 drawBezelWithFrame:inView: 方法。 目前,我必须使用 initTextCell:pullsDow
我是一名优秀的程序员,十分优秀!