2017-05-25 78 views
0

我創造,我添加了兩個任務,如下圖所示調度隊列和排隊的NSOperation

dispatch_queue_t serial = dispatch_queue_create("com.apple.serial", DISPATCH_QUEUE_SERIAL); 

**//Task 1** 
dispatch_async(serial, ^{ 

    [NMUserAPIManager getUserProfileData:^(NMUser *objUser) { 

     NSLog(@"Get User Profile ....."); 

     _objUser = objUser; 

    }]; 

}); 


**//Task 2** 
dispatch_async(serial, ^{ 

    [NMUserAPIManager getUserRecentTransactionData:^(NSDictionary *responseDictionary) { 
     _accountTableView.hidden = NO; 
     [self recentTransactionSetup:responseDictionary]; 

     NSLog(@"Get User Recent transaction"); 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self reloadTableData]; 
     }); 
    }]; 

}); 

裏面有兩個任務,我與NSURLSession調用Web服務的串行隊列。問題是,在我的任務1完成句柄Task2完成句柄被調用之前。根據理論,通過使用串行隊列,每個任務在執行之前等待前一個任務完成。我的理解是正確的。

+0

你的隊列序列化的東西是對'NMUserAPIManager'方法的調用。這意味着'getUserRecentTransactionData'將在調用'getUserProfileData'後被調用。它沒有對完成處理程序的順序做任何保證。 –

+0

您正在串行隊列中添加您的請求的發佈,但不是他們各自的響應。最簡單的解決方案是擺脫GCD,並從第一個請求的完成處理程序發出第二個請求。如果您確實想使用串行隊列來跟蹤這些請求,則可以將各個請求包裝在自定義的「NSOperation」子類中(請參閱https://stackoverflow.com/a/23837970/1271826或https:// stackoverflow的.com /一個/1271826分之24943851)。如果你只做了兩個請求,那可能是矯枉過正。 – Rob

回答

0

NSURLSession已經在後臺線程上運行,所以你在這裏看到的問題是,就你的串行隊列而言,一旦你調用'getUserProfileData:'技術上,你的隊列中該塊的工作就完成了,因爲NSURLSession正在另一個線程上運行。如果你在這裏的主要目標是簡單地撥打你的第二個任務,你的第一個完成後,我不認爲你需要你自己的隊列,你可能會更好簡單的做這樣的事情:

[NMUserAPIManager getUserProfileData:^(NMUser *objUser) { 

    NSLog(@"Get User Profile ....."); 

    _objUser = objUser; 

    [self getUserTransactions]; 

}]; 

-(void)getUserTransactions 
{ 
     [NMUserAPIManager getUserRecentTransactionData:^(NSDictionary *responseDictionary) { 
     _accountTableView.hidden = NO; 
     [self recentTransactionSetup:responseDictionary]; 

     NSLog(@"Get User Recent transaction"); 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self reloadTableData]; 
     }); 
    }]; 
} 

編輯:

如果你正在尋找一些更強大的東西,我會檢查出this post爲你如何可以子類NSOperation使你自己的異步操作,你可以使用NSOperationQueue。