Tôi phải đồng bộ hóa một loạt thông tin từ RestAPI của mình. Tôi phải làm 6 cuộc gọi RestAPI để hoàn thành công việc. Tôi đã thiết kế các cuộc gọi API với Blocks và trả về NSError nếu có. 3 trong số các cuộc gọi này nên thực thi lồng nhau vì cuộc gọi đầu tiên cung cấp thông tin cho người khác và cho phép thực hiện trong khi 3 cuộc gọi khác có thể chạy độc lập. Do cải thiện hiệu suất mạng, tôi đã thiết kế cuộc gọi đồng bộ hóa của mình như sau:NSBlockOperation, NSOperationQueue và Blocks
- 1 NSBlockOperation có chứa 3 khối lồng nhau đầu tiên;
- 1 NSBlockOperation có chứa ba khối khác;
- 1 NSBlockOperation mà tôi sử dụng làm "semphore" và cho tôi biết khi nào tất cả công việc đã hoàn thành.
NSBlockOperation cuối cùng có sự phụ thuộc vào hai NSBlockOperation trước đó.
Tôi cũng có NSOperationQueue chứa tất cả ba NSBlockOperation trong đó NSBlockOperation semaphore được thêm vào cuối cùng trong hàng đợi. Kết quả mà tôi sẽ đạt được là: hai khối đầu tiên được gọi là Đồng thời và khi kết thúc công việc của chúng, NSBlockOperation semaphore được gọi và trả về các điều khiển cho Người dùng cung cấp UIAlertMessage.
Kết quả không được giải thích trước đó: các điều khiển được trả về mà không cần chờ đến cuối khối syncAllBlocksInformation.
Bên dưới mã có chứa NSBlockOperation:
-(void)syncAllBlocksInformation:(void(^)(NSError *error))completion{
__block NSError *blockError = nil;
NSOperation *syncUserInfoOperation = [NSBlockOperation blockOperationWithBlock:^{
[dataSync syncUserInfo:tfMail.text password:tfPassword.text completion:^(NSError *error, NSNumber *idUser) {
if(!error){
[dataSync syncUserfilesInfo:idUser completion:^(NSError *error) {
if(!error){
[dataSync syncUserBookings:^(NSError *error) {
if(error){
blockError = error;
}
}];
}
else{
blockError = error;
}
}];
}
else{
blockError = error;
}
}];
}];
NSBlockOperation *otherSyncOperations = [NSBlockOperation blockOperationWithBlock:^{
[dataSync syncNewsInfo:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}];
}];
[otherSyncOperations addExecutionBlock:^{
[dataSync syncLocationsInfo:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}];
}];
[otherSyncOperations addExecutionBlock:^{
[dataSync syncExoticAnimalTypesAndAnimals:^(NSError *error) {
if(error){
blockError = error;
NSLog(@"error %@",error);
}
}];
}];
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"END");
}];
[completionOperation setCompletionBlock:^{
NSLog(@"Syc isEx %i",syncUserInfoOperation.isExecuting);
NSLog(@"other isEx %i",otherSyncOperations.isExecuting);
completion(blockError);
}];
NSOperationQueue *opQueue = [NSOperationQueue new];
[completionOperation addDependency:syncUserInfoOperation];
[completionOperation addDependency:otherSyncOperations];
[opQueue addOperation:syncUserInfoOperation];
[opQueue addOperation:otherSyncOperations];
[opQueue addOperation:completionOperation];
}
Và đây, mã mà các cuộc gọi trên khối:
-(IBAction)login:(id)sender{
[self dismissKeyboardOpened:nil];
hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[hud setLabelText:NSLocalizedString(@"login_hud_message", login_hud_message)];
[hud setMode:MBProgressHUDModeIndeterminate];
[self showHudAndNetworkActivity:YES];
[self syncAllBlocksInformation:^(NSError *error) {
[self showHudAndNetworkActivity:NO];
if(!error){
NSLog(@"End LOGIN");
[self showAlert:@"Login" message:@"Login OK" dismiss:YES];
}
else{
[self showAlert:@"Error" message:@"Login NO" dismiss:NO];
}
}];
}
Có chuyện gì vậy?
Bạn đã cố gắng thực hiện 'NSOperationQueue' một biến mẫu của lớp bao quanh? –
Tôi đã làm. Tôi đã khai báo là biến mẫu và tôi đã khởi tạo nó trong ViewDidLoad. Không có gì thay đổi. – dpizzuto