Question: I have a singleton name `CoreDataManager` which register the `mergeContextChangesForNotification` in it:

```
+ (id) sharedManager{
    static CoreDataManager *mSharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mSharedManager = [[CoreDataManager alloc] init];
    });
    return mSharedManager;
}

- (id)init
{
    self = [super init];
    if (self) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(mergeContextChangesForNotification:)
                                                     name:NSManagedObjectContextDidSaveNotification
                                                   object:nil];
        });
    }
    return self;
}

```

after i receive the notification:

```
- (void)mergeContextChangesForNotification:(NSNotification *)notification {
        [shareContext  performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 
                                        withObject:notification 
                                     waitUntilDone:YES];
}

```

I have two question here:

1. Should i use `performSelectorOnMainThread` here? since [this answer](https://stackoverflow.com/questions/19500820/gcd-vs-performselectorinbackground-performselectoronmainthread?answertab=votes#tab-top) says never.should i change it to GCD and use `dispatch_get_main_queue`??
2. Does the registration of `mergeContextChangesForNotification` in `init` is a good practice to ensure notification always register in main thread? which i read from [this answer](https://stackoverflow.com/questions/6197330/nsfetchedresultscontroller-misses-updates-on-merged-nsmanagedobjectcontext?answertab=votes#tab-top)

Answer: 
With the managed object concurrency types introduced in iOS 5/OS X 10.7 it is preferred
to use the `performBlock` methods to ensure that a Core Data operation is executed
on the right thread (more precisely: on the right queue).

So you would create the shared context with 

```
shareContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

```

and merge changes from other contexts with

```
- (void)mergeContextChangesForNotification:(NSNotification *)notification {
    [shareContext performBlock:^{
        [shareContext mergeChangesFromContextDidSaveNotification:notification];
    }];
}

```

Note also that (as stated in the `NSManagedObjectContext` documentation), it is 
recommended to register for save notifications only from known contexts.
With `object:nil` in your registration you might get unexpected notifications because system frameworks use Core Data internally.

So you should either register only for the contexts you create.
Alternatively, you can check that
a notification was sent from a context with the same persistent store coordinator:

```
- (void)mergeContextChangesForNotification:(NSNotification *)notification {
     NSManagedObjectContext *otherContext = [notification object];
     if (otherContext != shareContext &&
         [otherContext persistentStoreCoordinator] == [shareContext persistentStoreCoordinator]) {
              [shareContext performBlock:^{
                   [shareContext mergeChangesFromContextDidSaveNotification:notification];
              }];
    }
}

```

Finally, a notification method is always called on the thread on which it it *posted*.
It does not matter on which thread the notification is *registered*. Therefore 
dispatching the registration to the main thread is not necessary.
Check [TopSongs](https://developer.apple.com/library/ios/samplecode/TopSongs/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008925) sample application, keep in mind they are not perfect but most of the time may be used for reference. They are synchronizing `mergeChangesFromContextDidSaveNotification` calls to be made on the main thread only but doing it in a little more elegant way:

```
// This method will be called on a secondary thread. Forward to the main thread for safe handling of UIKit objects.
- (void)importerDidSave:(NSNotification *)saveNotification {

    if ([NSThread isMainThread]) {
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];
        [self.songsViewController fetch];
    } else {
        [self performSelectorOnMainThread:@selector(importerDidSave:) withObject:saveNotification waitUntilDone:NO];
    }
}

```

As for initialization, `-init` will be called on the same thread `+sharedManager` was called.

Also, since the second answer you linked is not very informative in terms of documentation, let me leave a link to [Concurrency with Core Data](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html#//apple_ref/doc/uid/TP40003385) section of the docs.