> On Jul 28, 2015, at 10:14 AM, Trygve Inda <cocoa...@xericdesign.com> wrote:
> 
>>> 
>>> On 28 Jul 2015, at 9:12 pm, Trygve Inda <cocoa...@xericdesign.com> wrote:
>>> 
>>> I gather that when using NSPrivateQueueConcurrencyType, all operations (a
>>> fetch for example) have to be done within a performBlock call.
>>> 
>> 
>> ...
>> 
>>> Then later, this context is used outside a performBlock:
>>> 
>>> 
>>> NSArray *matchingQuakes = [taskContext
>>> executeFetchRequest:matchingQuakeRequest error:&anyError];
>>> 
>>> 
>>> Why does this work?
>> 
>> You are supposed to call performBlock so that all accesses to the MOC are
>> serialized on the queue and so you get thread safety that way. However it's
>> quite possible to call the methods directly on the MOC in any thread context
>> and they will work, all the performBlock() actually does is queue the same
>> block of code onto the dispatch queue and when it's its turn, it executes by
>> calling [ moc executeFetch.. blah blah].
>> 
>> If you do that of course you have no thread safety any more and are likely to
>> blow up. In this case there's only one thread (I believe) and so the accesses
>> are serialized anyway and it works. It's a bad piece of code.
>> 
>> I filed an enhancement report requesting that the coredata stack assert if 
>> you
>> called a private queue MOC method from the wrong queue, I don't recall seeing
>> anything come of it, however I do remember there is quite a lot of logging 
>> you
>> can turn up on CoreData and it's possible one such log will tell you you're
>> doing this. 
> 
> If I do use performBlock and have to do several things:
> 
> This code is sitting inside a completion block for a URL downloader
> {
>    [self doSomething];
>    [myContext performBlock (do more stuff)];
>    [self doSomethingElse];
> }
> 
> 
> Since the perform block will run in a different thread, how can I make sure
> the "do more stuff" is finished before calling doSomethingElse?
> 
> Or in this case would using NSConfinementConcurrencyType be better since it
> is all within a completion block and presumably on it's own thread anyway.


Use performBlockAndWait instead of performBlock.

Or do something like (typed into Mail so not checked for syntax)

[myContext performBlock:^{
   //do whatever operation with myContext

   // assuming you want doSomethingElse done on main queue
   dispatch_async(dispatch_get_main_queue(), ^{
       [self doSomethingElse];
  });

}];

I believe NSConfementConcurrencyType is deprecated so you should not use it for 
new code.

I highly recommend you read through the documentation.

https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/index.html

HTH,
Dave Reed



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to