在NSUserDefaults中保存NSManagedObject

大家好(抱歉我的英文不好,我是法文),

我试图把我NSManagedObjectNSUserDefaults检索它的关系。 基本上我用NSCoding和我已经实现了所需的方法,但是因为它是NSManaged对象,init方法的签名是:init(实体:NSEntityDescription,insertIntoManagedObjectContext上下文:NSManagedObjectContext?)。

消息是“NSInvalidArgumentException”,原因是:“非法尝试在不同上下文中的对象之间build立关系”shop“

如果我在Address: self.shop = shop注释这行,它会一次又一次地创build我的实体。

这是我的代码:

把商店放在NSUserDefaults

 let selectedShop = shopFetchedResultsController!.fetchedObjects![indexPath.row] as! Shop let encodedShop = NSKeyedArchiver.archivedDataWithRootObject(selectedShop) NSUserDefaults.standardUserDefaults().setObject(encodedShop, forKey: "currentShop") 

并检索它:

 let encodedShop = NSUserDefaults.standardUserDefaults().objectForKey("currentShop") as! NSData let currentShop = NSKeyedUnarchiver.unarchiveObjectWithData(encodedShop) as! Shop 

实体店:

 import Foundation import CoreData @objc(Shop) class Shop: NSManagedObject, NSCoding { @NSManaged var name: String @NSManaged var phoneNumber: String @NSManaged var address: Address @NSManaged var products: NSSet // MARK: - Managed Object Context Insertable class var entityName: String { return "Shop" } struct Attributes { static let Name = "name" static let PhoneNumber = "phoneNumber" static let Address = "address" static let Products = "products" } override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) { super.init(entity: entity, insertIntoManagedObjectContext: context) } convenience init(name:String, phoneNumber:String, address:Address, products:NSSet) { self.init(entity: NSEntityDescription.entityForName("Shop", inManagedObjectContext: ManagedObjectContext.defaultContext)!, insertIntoManagedObjectContext: ManagedObjectContext.defaultContext) self.name = name self.phoneNumber = phoneNumber self.address = address self.products = products } required convenience init(coder aDecoder: NSCoder) { let name = aDecoder.decodeObjectForKey("name") as! String let phoneNumber = aDecoder.decodeObjectForKey("phoneNumber") as! String let address = aDecoder.decodeObjectForKey("address") as! Address let products = aDecoder.decodeObjectForKey("products") as! NSSet self.init(name: name, phoneNumber: phoneNumber, address: address, products: products) } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(name, forKey: "name") aCoder.encodeObject(phoneNumber, forKey: "phoneNumber") aCoder.encodeObject(address, forKey: "address") aCoder.encodeObject(products, forKey: "products") } 

地址实体:

 class Address: NSManagedObject, NSCoding { @NSManaged var city: String @NSManaged var country: String @NSManaged var ext: String? @NSManaged var number: NSNumber? @NSManaged var postalCode: String @NSManaged var street: String @NSManaged var customers: NSSet @NSManaged var shop: Shop // MARK: - Managed Object Context Insertable class var entityName: String { return "Address" } struct Attributes { static let City = "city" static let Country = "country" static let Ext = "ext" static let Number = "number" static let PostalCode = "postalCode" static let Street = "street" static let Customers = "customers" static let Shop = "shop" } override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) { super.init(entity: entity, insertIntoManagedObjectContext: context) } convenience init(city:String, country:String, ext:String?, number:NSNumber?, postalCode:String, street:String, customers: NSSet, shop: Shop) { self.init(entity: NSEntityDescription.entityForName(Address.entityName, inManagedObjectContext: ManagedObjectContext.defaultContext)!, insertIntoManagedObjectContext: ManagedObjectContext.defaultContext) self.city = city self.country = country self.ext = ext self.number = number self.postalCode = postalCode self.street = street self.customers = customers // self.shop = shop } required convenience init(coder aDecoder: NSCoder) { let city = aDecoder.decodeObjectForKey("city") as! String let country = aDecoder.decodeObjectForKey("country") as! String let ext : String? = aDecoder.decodeObjectForKey("ext") as? String let number : NSNumber? = aDecoder.decodeObjectForKey("number") as? NSNumber let postalCode = aDecoder.decodeObjectForKey("postalCode") as! String let street = aDecoder.decodeObjectForKey("street") as! String let customers = aDecoder.decodeObjectForKey("customers") as! NSSet let shop = aDecoder.decodeObjectForKey("shop") as! Shop self.init(city: city, country: country, ext: ext, number: number, postalCode: postalCode, street: street, customers: customers, shop: shop) } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(city, forKey: "city") aCoder.encodeObject(country, forKey: "country") aCoder.encodeObject(ext, forKey: "ext") aCoder.encodeObject(number, forKey: "number") aCoder.encodeObject(postalCode, forKey: "postalCode") aCoder.encodeObject(street, forKey: "street") aCoder.encodeObject(customers, forKey: "customers") aCoder.encodeObject(shop, forKey: "shop") } 

我甚至不知道是否是正确的方式来实现我的实体..

有关信息,我使用Swift2和Xcode7。 如果你需要更多的细节,只要告诉我,我可以为你提供其他的东西!

非常感谢您的帮助! 相信我,我花了3天没有解决scheme…

你从来不这样做。 核心数据对象只能保存在数据库中。 但是,您可以使用NSUserDefaults来保存任何您可以稍后检索并用于从核心数据中获取数据的密钥。