I'm finally getting to my To-Do list item to update old app code to use a Private Queue for my NSManagedObjectContext, but I'm running into some awkward situations and I can't find what I consider a clear answer.
If I'm accessing simple properties on an NSManagedObject, do I need to do that on the Private Queue as well?
It's causing me problems with table views and such. For example:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.textLabel.text = [object valueForKey:@"name"];
}
Is that ok to do when my context is in a private queue and I'm accessing the object value from the main ui thread?
The above is a very simple example, just to explain my point, but I've got more complicated examples throughout my code. Like when dealing with building swipe actions, I feel like I'm bouncing back and forth between ui-private-ui-private-ui in order to just handle a tap on a button.
Managed objects can only be used on the queue where they were fetched, so if you fetch on a private queue, you can only use the object on that queue. That includes accessing the properties of the object. There are a few exceptions to this rule-- you can look up the managed object ID, for example, and do a few other basic things (see the class docs for a full list), but that doesn't directly help here.
Depending on the details of your app, one or more of the following might help:
performBlockAndWait:
to retrieve the property values. This might block the UI if the private queue is busy with something else though.resultType
on the fetch request to NSDictionaryResultType
. This is fine if you're only reading the data, but it may be awkward to save changes since you don't have a managed object to work on.objectWithId:
to look up the same object on a different context that uses the main queue. Or if you have a bunch of objects, you can do a new fetch for all of the object IDs, again on the main queue.