gpt4 book ai didi

ios - 如何在 Swift 中的 NSCoding 初始化时返回预先存在的核心数据对象?

转载 作者:IT王子 更新时间:2023-10-29 05:37:47 26 4
gpt4 key购买 nike

当使用 NSCoding 初始化我的类的实例时,我想用 Core Data 数据库中的现有对象替换它,而不是调用:

super.init(entity: ..., insertIntoManagedObjectContext: ...)

因为这会将一个对象插入到数据库中。

class MyClass: NSManagedObject, NSCoding {
required init(coder aDecoder: NSCoder) {
// Find a preexisting object in the Core Data database

var ctx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
var fs = NSFetchRequest(entityName: "MyClass")

// ... Configure the fetch request based on values in the decoder

var err: NSErrorPointer = nil
var results = ctx.executeFetchRequest(fs, error: err)

// ... Error handling, etc

newObject = results[0] as! MyClass

// Attempt to replace self with the new object
self = newObject // ERROR: "Cannot assign to 'self' in a method"
}

func encodeWithCoder(aCoder: NSCoder) {
// Encode some identifying property for this object
}
}

这是一个 fairly common Objective-C 模式,但我不知道如何在 Swift 1.2 中复制它,因为将另一个对象分配给 self 会产生编译错误:

Cannot assign to 'self' in a method

即使成功了,Swift 似乎也要求我调用 NSManagedObject 的指定初始化程序,它将对象插入到数据库中。


如何在初始化时用数据库中预先存在的对象替换对象?如果它 可能(如果是这种情况请提供引用),我应该改用什么模式?

最佳答案

您可以使用 awakeAfterUsingCoder(_:)用于替换 self:

You can use this method to eliminate redundant objects created by the coder. For example, if after decoding an object you discover that an equivalent object already exists, you can return the existing object. If a replacement is returned, your overriding method is responsible for releasing the receiver.

class Item: NSManagedObject, NSCoding {

@NSManaged var uuid: String
@NSManaged var name: String?

override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}

required init(coder aDecoder: NSCoder) {
let ctx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
let entity = NSEntityDescription.entityForName("Item", inManagedObjectContext: ctx)!

// Note: pass `nil` to `insertIntoManagedObjectContext`
super.init(entity: entity, insertIntoManagedObjectContext: nil)
self.uuid = aDecoder.decodeObjectForKey("uuid") as! String
}

func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.uuid, forKey: "uuid")
}

override func awakeAfterUsingCoder(aDecoder: NSCoder) -> AnyObject? {
let ctx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
let fetch = NSFetchRequest(entityName: "Item")
fetch.predicate = NSPredicate(format: "uuid == %@", self.uuid)

if let obj = ctx.executeFetchRequest(fetch, error: nil)?.first as? Item {
// OK, the object is still in the storage.
return obj
}
else {
// The object has already been deleted. so insert and use `self`.
ctx.insertObject(self)
return self
}
}
}

关于ios - 如何在 Swift 中的 NSCoding 初始化时返回预先存在的核心数据对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31372584/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com