如何使用 iOS 中尚未保存的 objectID 访问 NSManagedObject 实体?
How to access NSManagedObject entity using objectID which is not saved yet in iOS?
我使用私有队列 MOC 创建了一个实体并调用 performBlock()
异步保存它。
假设我想要这个新创建的实体在其他上下文/MOC 中,所以我只有一种访问它的方法是使用对象 ID。
但是由于它是保存实体的异步调用,可能会出现实体尚未保存的情况,我想在 performBlock()
之后立即访问它,但在其他上下文中。
这种情况下访问方式是什么?
提前致谢!
更新
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = mainThreadManagedObjectContext()
let newUser = Contact(nameStr: "name", moc: privateMOC)
这是我创建新实体的通用代码,例如:
init(nameStr: String, moc:NSManagedObjectContext) {
let mEntity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: moc)
super.init(entity: mEntity!, insertIntoManagedObjectContext: moc)
name = nameStr
}
创建后,我立即将其保存为:
performBlock { () -> Void in
do {
try privateMOC.save()
}catch {
fatalError("Error asynchronously saving private moc - \(errorMsg): \(error)")
}
}
//正在访问
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = mainThreadManagedObjectContext()
let pred = NSPredicate(format: "name == %@", "name")
if let results = DatabaseInterface.sharedInstance.fetchEntityFromCollection("Contact", withPredicate: pred, moc: privateMOC) {
if let user = results.last {
return user as! Contact
}
}
else {
DDLogWarn("No user found")
}
我没有获得任何用户,但我可以看到这个新联系人在使用 sqlitebrowser
查看时保存在数据库中
代码缩进请见谅:(
你问的是不可能的。
当您在一个上下文中创建托管对象时,它只存在于内存中,直到您保存更改。没有其他托管对象上下文可以访问它,即使您使用对象 ID。其他上下文无法从持久存储文件中查找数据,也无法从其他上下文中获取数据。它根本无法获取对象。您需要等到保存完成。
根据您应用的结构,您可以尝试以下几种方法:
- 使用
performBlockAndWait
而不是 performBlock
,这样您就可以在块完成时知道保存已完成。
- 继续使用
performBlock
,但将调用置于该块内,从而导致在不同的上下文中访问对象——通过对其他上下文的嵌套 performBlock
调用。
我使用私有队列 MOC 创建了一个实体并调用 performBlock()
异步保存它。
假设我想要这个新创建的实体在其他上下文/MOC 中,所以我只有一种访问它的方法是使用对象 ID。
但是由于它是保存实体的异步调用,可能会出现实体尚未保存的情况,我想在 performBlock()
之后立即访问它,但在其他上下文中。
这种情况下访问方式是什么?
提前致谢!
更新
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = mainThreadManagedObjectContext()
let newUser = Contact(nameStr: "name", moc: privateMOC)
这是我创建新实体的通用代码,例如:
init(nameStr: String, moc:NSManagedObjectContext) {
let mEntity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: moc)
super.init(entity: mEntity!, insertIntoManagedObjectContext: moc)
name = nameStr
}
创建后,我立即将其保存为:
performBlock { () -> Void in
do {
try privateMOC.save()
}catch {
fatalError("Error asynchronously saving private moc - \(errorMsg): \(error)")
}
}
//正在访问
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = mainThreadManagedObjectContext()
let pred = NSPredicate(format: "name == %@", "name")
if let results = DatabaseInterface.sharedInstance.fetchEntityFromCollection("Contact", withPredicate: pred, moc: privateMOC) {
if let user = results.last {
return user as! Contact
}
}
else {
DDLogWarn("No user found")
}
我没有获得任何用户,但我可以看到这个新联系人在使用 sqlitebrowser
代码缩进请见谅:(
你问的是不可能的。
当您在一个上下文中创建托管对象时,它只存在于内存中,直到您保存更改。没有其他托管对象上下文可以访问它,即使您使用对象 ID。其他上下文无法从持久存储文件中查找数据,也无法从其他上下文中获取数据。它根本无法获取对象。您需要等到保存完成。
根据您应用的结构,您可以尝试以下几种方法:
- 使用
performBlockAndWait
而不是performBlock
,这样您就可以在块完成时知道保存已完成。 - 继续使用
performBlock
,但将调用置于该块内,从而导致在不同的上下文中访问对象——通过对其他上下文的嵌套performBlock
调用。