2014-06-18 17 views
1

我有一种方法可以帮助我将本地的standardUserDefaults与Web服务同步。首先,我需要确保数据已成功同步,然后我可以让方法返回。我目前正在努力解决的问题是,我不能得到的GCD 执行&完成按照一定顺序的任务:首先发布到Web服务和其次返回。GCD dispatch_sync没有按顺序完成执行

问题是第二个dispatch_sync任务先完成执行,然后是第一个dispatch_sync任务。如何确保执行按计划进行?由于NSURLSessionDataTask,这是一个特例吗?

非常感谢!

-(void) syncLocalStorageToMMUsersDB:(void(^)(bool success))handler 
{ 
__block bool fb_sync_success = 0; 

dispatch_queue_t requestQueue = dispatch_queue_create("com.micromorts.request", DISPATCH_QUEUE_SERIAL); 


//if logged in with Facebook, then sync it 
if ([_defaults stringForKey:MMFBIdPrefsKey]) { 
    // Start NSURLSession 
    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]]; 

    // POST parameters 
    NSURL *url = [NSURL URLWithString:@"http://THE.URL.GOES.HERE"]; 
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; 
    NSString *params = [POST PARAMS GO HERE]; 
    [urlRequest setHTTPMethod:@"POST"]; 
    [urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; 

    // NSURLSessionDataTask returns data, response, and error 

    NSURLSessionDataTask *dataTask =[defaultSession dataTaskWithRequest:urlRequest 
    completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     // Handle response 
     NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; 
     NSInteger statusCode = [httpResponse statusCode]; 
     if(error == nil) { 
      if (statusCode == 404) { 
       NSLog(@"MMAuth.m :: syncLocalStorageToMMUsersDB FB :: FB User not found"); 
       fb_sync_success = false; 

      } else if (statusCode == 200) { 
       NSLog(@"MMAuth.m :: syncLocalStorageToMMUsersDB FB :: Successfully synced "); 
       fb_sync_success = true; 

      } else { 
      NSLog(@"MMAuth.m :: syncLocalStorageToMMUsersDB FB :: Sync fail "); 
       fb_sync_success = false; 
      } 
     } 
    } 
    ]; 
    //This should finish EXECUTING first 
    dispatch_sync(requestQueue, ^{ 
     [dataTask resume]; 
    }); 
} 

//This should finish EXECUTING second 
dispatch_sync(requestQueue, ^{ 

    if (fb_sync_success){ 
     NSLog(@"SUCCESS"); 
    } else { 
     NSLog(@"FAILED"); 
    } 

}); 
} 
+0

是什么让你认为提交给'requestQueue'的第一个任务没有完成?在调用'-resume'之后放一个日志。我敢打赌,你会在成功或失败之前看到它。我认为你假设'-resume'方法以某种方式等待,直到任务完成。它没有。它只是将其从暂停状态切换到暂停状态;它允许它继续。从暂停切换到不需要很少的时间。这与任务完成需要多少时间无关。 –

回答

3

如果调用[dataTask resume];是异步的,那么这将dispatch_sync()-resume执行和然后随后dispatch_sync()将被排队和执行之后立即(但加载的数据之前)立即返回。

将您的SUCCESS/FAILED逻辑移入完成处理程序块;这就是完成处理程序存在的原因。

+0

非常感谢,宝贝! –