简体   繁体   中英

dispatch_async(dispatch_get_main_queue() inside NSManagedObjectContext performBlock

What I want to do is create a async core data task on a background thread so as not to chew up the main thread, but I also want to do main thread work once the work is done...

Here's my task

  -(void)doTaskwithCompletion:(coreDataCompletion)complete
  {
    [self.backgroundManagedObjectContext performBlock:^{

        // do my BG core data task

        [self saveContext:self.backgroundManagedObjectContext];
        complete(YES);

    }];
   }

Here's my block method

            [[MYCoreDataManager sharedInstance]doTaskwithCompletion:^(BOOL complete) {

                if (complete == YES) {

                    dispatch_async(dispatch_get_main_queue(), ^{

                         // back to the main thread                            
                    });
                }

            }];

Something tells me this is wrong... but I can't find another way to put myself back on the main thread once the block has completed... notifications seem way too clunky.

I suppose in a nutshell my question is can I call dispatch_async(dispatch_get_main_queue() inside moc performBlock:^ ?

Essentially

  -(void)doTaskwithCompletion:(coreDataCompletion)complete
  {
    [self.backgroundManagedObjectContext performBlock:^{

        // do my BG core data task

        [self saveContext:self.backgroundManagedObjectContext];
        dispatch_async(dispatch_get_main_queue(), ^{

           // back to the main thread    

        });

    }];
   }

I guess you know that it is a very common pattern to call something async and inside go back to mainQueue, ie for updating the UI:

dispatch_async(globalQueue, ^{
    // do something
    dispatch_async(mainQueue, ^{ 
        // update UI
    });
});

As you already named your variable self.backgroundManagedObjectContext you have probably heart of Multi-Context CoreData and I understand your concerns. As long as you are not trying to change something with this block for CoreData (on any Context) you are probably fine.

Just make sure that you use the correct initializer for your contexts, ie [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

"I suppose in a nutshell my question is can I call dispatch_async(dispatch_get_main_queue() inside moc performBlock:^?"

The answer is yes! In fact, you are doing the REVERSE of that when you call your performBlock from the main thread, right? This is a common feature of iOS. A cleaner way to do it perhaps is passing in a completion, and in that completion calling main...

right now, you have:

dispatch_async(dispatch_get_main_queue(), ^{

       // back to the main thread  
       completion()



    });

You could also write:

-(void)doTaskwithCompletion:(coreDataCompletion)complete
{
[self.backgroundManagedObjectContext performBlock:^{

    // do my BG core data task

    [self saveContext:self.backgroundManagedObjectContext];
    complete()

}];
}

where complete has in it a call to the main thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM