Reputation: 4287
(I'm sorry if this question is kind of confusing/imprecise. I'm just learning advanced CoreData usage and I don't know the terminology and stuff very well).
I have a singleton Game
that holds certain data you need during the game. For example, you can access currentSite
(Site
is a CoreData Entity
) from there to get the Site
the user is currently at:
// 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
}
You see, I retrieve the currentSite
by using the managedObjectContext.object(with:)
method.
The documentation of this method says:
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. (...)
I'm not quite sure about the following:
// 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)
}
}
The second print
function is using the managedObjectContext
of the main queue (which is different to the private one used inside performBackgroundTask {...}
).
It actually does print:
50 // the start value
92
My question: Is it guaranteed that managedObjectContext.object(with:)
returns the current object (that is up-to-date), even if it has been changed in another context
? The documentation says that it will be fetched if it's a new object that's not known to the context
.
But what if an object changes?
I'm not sure if it's just a coincidence that the example code from above is working like expected.
Thanks for any help/explanation! I'm eager to learn about this kind of stuff.
Upvotes: 3
Views: 69
Reputation: 1224
No it is not guaranteed. If managed object is already registered in context then it will return this object. What's more, if object with given id (NSManagedObjectId) doesn't exist in persistent store then your app will crash as soon as you try to use any of its properties.
Upvotes: 1