managedObjectContext.object(with:) 如果另一个(私有)managedObjectContext 更改并保存它是否总是重新获取数据?
Does managedObjectContext.object(with:) always refetch data if another (private) managedObjectContext changed and saved it?
(如果这个问题有点confusing/imprecise,我很抱歉。我只是在学习高级 CoreData 用法,我不太了解术语和其他东西)。
我有一个单例 Game
可以保存您在游戏中需要的某些数据。例如,您可以从那里访问 currentSite
(Site
是一个 CoreData Entity
)以获取用户当前所在的 Site
:
// I created the Site in a background queue (when the game started), then saved the objectID and here I load the objectID
public var currentSiteObjectID: NSManagedObjectID {
let objectIDuri = UserDefaults.standard.url(forKey: Keys.forGameObject.currentSiteObjectIDURI)!
return appDelegate.persistentContainer.persistentStoreCoordinator.managedObjectID(forURIRepresentation: objectIDuri)!
}
// managedObjectContext is the one running on the main queue
public var currentSite: Site! {
return managedObjectContext.object(with: currentSiteObjectID) as! Site
}
你看,我使用 managedObjectContext.object(with:)
方法检索 currentSite
。
这个方法的文档说:
Returns the object for a specified ID.
If the object is not registered
in the context, it may be fetched or returned as a fault. (...)
我不太确定以下内容:
// Each Site has resources that you can access like this
print(Game.shared.currentSite!.resourceSet!.iron)
appDelegate.persistentContainer.performBackgroundTask { (context) in
let currentSite = context.object(with: Game.shared.currentSiteObjectID) as! Site
// Here I increase the iron resource
currentSite.resourceSet!.iron += 42
do {
try context.save()
} catch let error as NSError {
fatalError("\(error.debugDescription)")
}
DispatchQueue.main.async {
print(Game.shared.currentSite!.resourceSet!.iron)
}
}
第二个print
函数正在使用主队列的managedObjectContext
(这与performBackgroundTask {...}
中使用的私有队列不同)。
它确实打印:
50 // the start value
92
我的问题:是否保证 managedObjectContext.object(with:)
returns 当前对象(即最新的),即使它已在另一个 context
中更改?文档说,如果它是 context
不知道的新对象,它将被获取。
但是,如果对象发生变化怎么办?
我不确定上面的示例代码是否按预期工作只是巧合。
感谢任何help/explanation!我很想了解这种东西。
不,不能保证。如果托管对象已经在上下文中注册,那么它将 return 这个对象。此外,如果持久存储中不存在具有给定 ID (NSManagedObjectId) 的对象,那么只要您尝试使用其任何属性,您的应用就会崩溃。
(如果这个问题有点confusing/imprecise,我很抱歉。我只是在学习高级 CoreData 用法,我不太了解术语和其他东西)。
我有一个单例 Game
可以保存您在游戏中需要的某些数据。例如,您可以从那里访问 currentSite
(Site
是一个 CoreData Entity
)以获取用户当前所在的 Site
:
// I created the Site in a background queue (when the game started), then saved the objectID and here I load the objectID
public var currentSiteObjectID: NSManagedObjectID {
let objectIDuri = UserDefaults.standard.url(forKey: Keys.forGameObject.currentSiteObjectIDURI)!
return appDelegate.persistentContainer.persistentStoreCoordinator.managedObjectID(forURIRepresentation: objectIDuri)!
}
// managedObjectContext is the one running on the main queue
public var currentSite: Site! {
return managedObjectContext.object(with: currentSiteObjectID) as! Site
}
你看,我使用 managedObjectContext.object(with:)
方法检索 currentSite
。
这个方法的文档说:
Returns the object for a specified ID.
If the object is not registered in the context, it may be fetched or returned as a fault. (...)
我不太确定以下内容:
// Each Site has resources that you can access like this
print(Game.shared.currentSite!.resourceSet!.iron)
appDelegate.persistentContainer.performBackgroundTask { (context) in
let currentSite = context.object(with: Game.shared.currentSiteObjectID) as! Site
// Here I increase the iron resource
currentSite.resourceSet!.iron += 42
do {
try context.save()
} catch let error as NSError {
fatalError("\(error.debugDescription)")
}
DispatchQueue.main.async {
print(Game.shared.currentSite!.resourceSet!.iron)
}
}
第二个print
函数正在使用主队列的managedObjectContext
(这与performBackgroundTask {...}
中使用的私有队列不同)。
它确实打印:
50 // the start value
92
我的问题:是否保证 managedObjectContext.object(with:)
returns 当前对象(即最新的),即使它已在另一个 context
中更改?文档说,如果它是 context
不知道的新对象,它将被获取。
但是,如果对象发生变化怎么办?
我不确定上面的示例代码是否按预期工作只是巧合。
感谢任何help/explanation!我很想了解这种东西。
不,不能保证。如果托管对象已经在上下文中注册,那么它将 return 这个对象。此外,如果持久存储中不存在具有给定 ID (NSManagedObjectId) 的对象,那么只要您尝试使用其任何属性,您的应用就会崩溃。