Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to do Core Data reads within performBlock when using NSMainQueueConcurrencyType?

According to Daniel Eggert's answer in this question, when using a managed object context with NSPrivateQueueConcurrencyType it's necessary to do anything that touches it or objects that belong to it within performBlock: or performBlockAndWait:

Is the same true for NSMainQueueConcurrencyType? Imagine the following code running on the main thread, in a UIViewController for instance:

self.moc = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
//moc setup

__block RHWidget *widget = nil;

[self.moc performBlockAndWait:^{
    widget = [(RHWidget *)[self.moc objectWithID:self.widgetObjectID] retain];
}];

self.labelView.text = widget.descriptionString;

[widget release];

Is it safe to use the widget outside the block, since we know we're on the main thread? Or it is it necessary to do this:

__block NSString *description = nil;

[self.moc performBlockAndWait:^{
    RHWidget *widget = (RHWidget *)[self.moc objectWithID:self.widgetObjectID];
    description = [widget.descriptionString copy];
}];

self.labelView.text = description;

[description release];

Do things change if there's another NSManagedObjectContext out there, possibly of the private queue type, doing work in blocks and pushing changes up to self.moc as a parentContext?

This is a slightly contrived example of course, but it'd be nice to safely pass that widget to, for instance, a modal view controller that needs to access some of the widget's properties. Should I be passing the objectID of the widget instead and refetching it within performBlock: in the new view controller?

like image 405
roland Avatar asked Apr 03 '12 15:04

roland


People also ask

How does Core Data handle multithreading?

To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization. Managed objects retrieved from a context are bound to the same queue that the context is bound to.

What are concurrency type in Core Data?

Concurrency is the ability to work with the data on more than one queue at the same time. If you choose to use concurrency with Core Data, you also need to consider the application environment. For the most part, AppKit and UIKit are not thread-safe.

What is Core Data in iOS Swift?

Getting Started Core Data (CRUD) with Swift. Core Data is a graphical and persistence framework, which is used in Apple devices with operating systems macOS and iOS. Core Data was first introduced in Mac OS X 10.4 Tiger and iOS with iPhone SDK 3.0.


1 Answers

Update: According to WWDC 2011 Session 303 (What's New in Core Data on iOS), NSMainQueueConcurrencyType is intended to allow normal messaging on the main thread; you only need to use -performBlock: when interacting with the context from a different thread. (Still-relevant parts of my original answer below.)


I've made an app or two that modifies Xcode's default "Master-Detail" app template to make the "main" MOC (created by the app delegate and passed among view controllers) main-queue-only, and parent to a private-queue context that I use for background operations like importing data from a web fetch. Thus, most uses of the context and its objects happen without being wrapped in performBlock:. (The only time I do use performBlock: is to push changes from the background-task context back to the main one to update the UI.) Works just fine.

like image 104
rickster Avatar answered Sep 27 '22 21:09

rickster