我有两个类:Contact 和 Bill。 Contact 有一个类型为 Bill 的数组。
当我坚持使用 NSKeyedArchiver 时,我的联系人保持得很好,但是,它不会保持 Bill 数组。
每次添加账单或联系人时,我都会在持久化中调用 insertNewObject()
方法。
这是我的类(class):
/* Persist.swift */
import Foundation
class Persist {
static let sharedInstance = Persist()
let delegate = UIApplication.sharedApplication().delegate as! AppDelegate
var contactsFilePath : String {
let manager = NSFileManager.defaultManager()
let url = manager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! as NSURL
return url.URLByAppendingPathComponent("\(delegate.userId):objectsArrayz").path!
}
func insertNewObject(){
NSKeyedArchiver.archiveRootObject(delegate.contacts!, toFile: contactsFilePath)
}
func retrieveContracts(){
if let array = NSKeyedUnarchiver.unarchiveObjectWithFile(contactsFilePath) as? [Contact] {
delegate.contacts = array
}
}
func deleteContact(rowNum : Int){
delegate.contacts!.removeAtIndex(rowNum)
NSKeyedArchiver.archiveRootObject(delegate.contacts!, toFile: contactsFilePath)
}
/* Contact.swift */
import Foundation
class Contact : NSObject, NSCoding{
var image : UIImage?
var firstName : String?
var lastName : String?
var email : String?
var phoneNumber : String?
var address : String?
var bills : [Bill]?
init(image: UIImage, firstName : String, lastName : String, email : String, phoneNumber : String, address : String, bills : [Bill]) {
self.image = image
self.firstName = firstName
self.lastName = lastName
self.email = email
self.phoneNumber = phoneNumber
self.address = address
self.bills = bills
}
// MARK: NSCoding
required convenience init?(coder decoder: NSCoder) {
guard let image = decoder.decodeObjectForKey("image") as? UIImage,
let firstName = decoder.decodeObjectForKey("firstName") as? String,
let lastName = decoder.decodeObjectForKey("lastName") as? String,
let email = decoder.decodeObjectForKey("email") as? String,
let phoneNumber = decoder.decodeObjectForKey("phoneNumber") as? String,
let address = decoder.decodeObjectForKey("address") as? String,
let bills = decoder.decodeObjectForKey("bills") as? [Bill]
else {
return nil
}
self.init(
image: image,
firstName: firstName,
lastName : lastName,
email : email,
phoneNumber : phoneNumber,
address : address,
bills : bills
)
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.image, forKey: "image")
coder.encodeObject(self.firstName, forKey: "firstName")
coder.encodeObject(self.lastName, forKey: "lastName")
coder.encodeObject(self.email, forKey: "email")
coder.encodeObject(self.phoneNumber, forKey: "phoneNumber")
coder.encodeObject(self.address, forKey: "address")
coder.encodeObject(self.bills, forKey: "bills")
}
}
/* Bill.swift*/
import Foundation
class Bill : NSObject, NSCoding{
var service : String?
var subtotal : Double?
var taxes : Double?
var total : Double?
init(service : String, subtotal : Double, taxes : Double, total: Double) {
self.service = service
self.subtotal = subtotal
self.taxes = taxes
}
// MARK: NSCoding
required convenience init?(coder decoder: NSCoder) {
guard let service = decoder.decodeObjectForKey("service") as? String,
let subtotal = decoder.decodeObjectForKey("subtotal") as? Double,
let taxes = decoder.decodeObjectForKey("taxes") as? Double,
let total = decoder.decodeObjectForKey("total") as? Double
else {
return nil
}
self.init(
service: service,
subtotal: subtotal,
taxes: taxes,
total: total
)
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.service, forKey: "service")
coder.encodeObject(self.subtotal, forKey: "subtotal")
coder.encodeObject(self.taxes, forKey: "taxes")
coder.encodeObject(self.total, forKey: "total")
}
}
最佳答案
这里是来自苹果开发文档的指南(在 Objective-C 中):
Discussion You must return self from initWithCoder:. If you have an advanced need that requires substituting a different object after decoding, you can do so in awakeAfterUsingCoder:
- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder];
// Implementation continues
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
_firstName = [coder decodeObjectForKey:ASCPersonFirstName];
_lastName = [coder decodeObjectForKey:ASCPersonLastName];
_height = [coder decodeFloatForKey:ASCPersonHeight];
}
return self;
}
关于ios - NSCoding 自定义对象子数组未持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36458499/