using dispatch_sync in Grand Central Dispatch

前端 未结 8 2091
孤城傲影
孤城傲影 2020-11-30 17:25

Can anyone explain with really clear use cases what the purpose of dispatch_sync in GCD is for? I can\'t understand where and why I would have to u

8条回答
  •  南方客
    南方客 (楼主)
    2020-11-30 17:47

    If you want some samples of practical use look at this question of mine:

    How do I resolve this deadlock that happen ocassionally?

    I solve it by ensuring that my main managedObjectContext is created on the main thread. The process is very fast and I do not mind waiting. Not waiting means I will have to deal with a lot of concurency issue.

    I need dispatch_sync because some code need to be done on main thread, which is the different thread than the one where to code is being executed.

    So basically if you want the code to 1. Proceed like usual. You don't want to worry about race conditions. You want to ensure that the code is completed before moving on. 2. Done on a different thread

    use dispatch_sync.

    If 1 is violated, use dispatch_async. If 2 is violated just write the code like usual.

    So far, I only do this once, namely when something need to be done on main thread.

    So here's the code:

    +(NSManagedObjectContext *)managedObjectContext {
    
    
        NSThread *thread = [NSThread currentThread];
        //BadgerNewAppDelegate *delegate = [BNUtilitiesQuick appDelegate];
        //NSManagedObjectContext *moc = delegate.managedObjectContext;
    
        if ([thread isMainThread]) {
            //NSManagedObjectContext *moc = [self managedObjectContextMainThread];
            return [self managedObjectContextMainThread];
        }
        else{
            dispatch_sync(dispatch_get_main_queue(),^{
                [self managedObjectContextMainThread];//Access it once to make sure it's there
            });
        }
    
        // a key to cache the context for the given thread
        NSMutableDictionary *managedObjectContexts =[self thread].managedObjectContexts;
    
        @synchronized(self)
        {
            if ([managedObjectContexts objectForKey:[self threadKey]] == nil ) {
                NSManagedObjectContext *threadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
                threadContext.parentContext = [self managedObjectContextMainThread];
                //threadContext.persistentStoreCoordinator= [self persistentStoreCoordinator]; //moc.persistentStoreCoordinator;//  [moc persistentStoreCoordinator];
                threadContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
                [managedObjectContexts setObject:threadContext forKey:[self threadKey]];
            }
        }
    
    
        return [managedObjectContexts objectForKey:[self threadKey]];
    }
    

提交回复
热议问题