In iOS 5, NSManagedObjectContext
has a couple of new methods, performBlock:
and performBlockAndWait:
. What are these methods actually used for? What do they replace in older versions? What kind of blocks are supposed to be passed to them? How do I decide which to use? If anyone has some examples of their use it would be great.
The methods performBlock:
and performBlockAndWait:
are used to send messages to your NSManagedObjectContext
instance if the MOC was initialized using NSPrivateQueueConcurrencyType
or NSMainQueueConcurrencyType
. If you do anything with one of these context types, such as setting the persistent store or saving changes, you do it in a block.
performBlock:
will add the block to the backing queue and schedule it to run on its own thread. The block will return immediately. You might use this for long persist operations to the backing store.
performBlockAndWait:
will also add the block to the backing queue and schedule it to run on its own thread. However, the block will not return until the block is finished executing. If you can't move on until you know whether the operation was successful, then this is your choice.
For example:
__block NSError *error = nil;
[context performBlockAndWait:^{
myManagedData.field = @"Hello";
[context save:&error];
}];
if (error) {
// handle the error.
}
Note that because I did a performBlockAndWait:
, I can access the error outside the block. performBlock:
would require a different approach.
From the iOS 5 core data release notes:
NSManagedObjectContext now provides structured support for concurrent operations. When you create a managed object context using initWithConcurrencyType:, you have three options for its thread (queue) association
Confinement (NSConfinementConcurrencyType).
This is the default. You promise that context will not be used by any thread other than the one on which you created it. (This is exactly the same threading requirement that you've used in previous releases.)
Private queue (NSPrivateQueueConcurrencyType).
The context creates and manages a private queue. Instead of you creating and managing a thread or queue with which a context is associated, here the context owns the queue and manages all the details for you (provided that you use the block-based methods as described below).
Main queue (NSMainQueueConcurrencyType).
The context is associated with the main queue, and as such is tied into the application’s event loop, but it is otherwise similar to a private queue-based context. You use this queue type for contexts linked to controllers and UI objects that are required to be used only on the main thread.
performBlockAndWait:
doesn't block the main thread, does it? It's confusing that it can be attached to the main run loop, but has a name that makes it seem like it makes you wait. –
Oklahoma performBlock
or performBlockAndWait
or can I do just like before? –
Kraut -performBlockAndWait:
will not return until the ^{block}
is finished executing. It behaves just like any plain old nested subroutine. It's execution is synchronous. –
Nagle performBlock
, or only the saving part ? –
Marcelline They allow you to access the same managedObjectContext
accross threads.
I am not really sure I am correct, but this is how I use it.
You use performBlockAndWait
is like "usual". You do not need it if you execute the managedObjectContext only on one thread. If you execute it on many threads then yes you will need performBlock
.
So, if you're on main thread, you do not need to do performBlockAndWait
for the main managedObjectContext
. At least I don't and is doing fine.
However if you access that managedObjectContext
on other threads then yes you will need to do performBlockAndWait
.
So that's the purpose of performBlock
and performBlockAndWait
.
Would someone please correct me if I am wrong here. Of course if you access the context only on one thread then you can simply use the default.
NSManagedObjectContext
: Core Data uses thread (or serialized queue) confinement to protect managed objects and managed object contexts. A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method. You should not, therefore, initialize a context on one thread then pass it to a different thread.
Thereby, NSManagedObjectContexts
are NOT thread safe and you can't access them across threads. –
Gurolinick synchronous
or asynchronous
processing). See answer from @Snapshot and related comments for discussion regarding this. –
Gurolinick NSManagedObjectContexts
across threads. What you can't do is pass NSManagedObjects
across threads. You can say to your context in the main thread to save by doing [mainContext performBlock:^{ NSError *error = nil; [mainContext save:&error]; };
from a different thread. –
Kraut performBlockAndWait:
runs on the context's thread, just like performBlock:
does, but makes caller's thread wait until block execution is finished. –
Neely po [NSThread currentThread]
in the debugger inside and outside performBlockAndWait:
call and... Oh, it really run on the caller thread. Thank you for the link. –
Neely © 2022 - 2024 — McMap. All rights reserved.