我有四个api要求。它们应按以下顺序排列:
apiSyncDataToCloud;
apiSyncImagesToServer;
apiDeleteDataFromCloud;
apiSyncDataFromCloudInBackground;
无论前一个成功完成还是失败,都会被调用。
此外,他们每个人都有成功和失败完成块。
成功完成块数据库更新。
所有这些过程都必须在后台中执行,并且要完成 不能。 Api调用当然是在后台执行的,但是一旦调用完成,就会在主线程上执行数据库更新,从而冻结应用程序。
所以,我选择了几个解决方案:
尝试以下代码:
NSOperationQueue *queue = [NSOperationQueue new];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
[self apiSyncDataToCloud];
}];
[queue addOperationWithBlock:^{
[self apiSyncImages];
}];
[queue addOperationWithBlock:^{
[self apiDeleteDataFromCloud];
}];
[queue addOperationWithBlock:^{
[self apiSyncDataFromCloudInBackground];
}];
但这只能保证api方法调用将按顺序执行。但他们的结果没有特定的顺序。也就是说,方法调用将按指定的顺序进行,但apiSyncImagesToServer的成功块可能在apiSyncDataToCloud成功阻止之前被调用。
然后我选择了以下解决方案:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self apiSyncDataToCloud];
});
在apiSyncDataToCloud的成功和失败块中,我调用了apiSyncImagesToServer。这也没有用。
现在我只是按照我的最后一个解决方案。我只是在调用apiSyncDataToCloud。
在成功完成块中,此方法首先更新数据库,然后调用其他api。
在失败完成块中,此方法只是在不更新数据库的情况下进行api调用。
例如 -
apiSyncDataToCloud的结构如下:
-(void)apiSyncDataToCloud{
NSLog(@"method 1");
NSMutableDictionary *dicDataToBeSynced = [NSMutableDictionary dictionary];
dicDataToBeSynced = [self getDataToBeSynced];
if (dicDataToBeSynced.count!=0) {
if ([[StaticHelper sharedObject] isInternetConnected]) {
[[ApiHandler sharedObject] postRequestWithJsonString:API_SYNC_DATA_TO_CLOUD andHeader:[UserDefaults objectForKey:kAuthToken] forHeaderField:kAccessToken andParameters:dicDataToBeSynced WithSuccessBlock:^(NSURLResponse *response, id resultObject, NSError *error) {
NSLog(@"Data synced successfully to server");
[self updateColumnZSYNC_FLAGForAllTables];//updating db
[self apiSyncImagesToServer];//api call
} andFailureBlock:^(NSURLResponse *task, id resultObject, NSError *error) {
NSLog(@"Data syncing to cloud FAILED");
[self apiSyncImagesToServer];//simply make api call without updating db
}];
}
}else{
[self apiSyncImagesToServer];make api call even if no data to be synced found
}
}
同样,在apiSyncImagesToServer里面我正在调用apiDeleteDataFromCloud .....
结果我的问题仍然存在。当成功阻止更新数据库,下载图像时,应用程序会冻结...正在主线程上执行的所有操作。
Plz让我知道更清洁,更好的解决方案。
答案 0 :(得分:2)
您可以逐个创建自己的自定义队列和呼叫请求。 即。
dispatch_queue_t myQueue;//declare own queue
if (!myQueue) {//check if queue not exists
myQueue = dispatch_queue_create("com.queue1", NULL); //create queue
}
dispatch_async(myQueue, ^{[self YOUR_METHOD_NAME];});//call your method in queue block
如果您想在接收数据后更新某些UI,请在主线程上更新UI。
答案 1 :(得分:1)
1)最好在这种情况下使用AFNetworking
。因为AFNetworking提供了更好的方式来处理Main&背景线程。
AFNetworking支持成功和失败块,因此您可以通过先前WS Api调用的成功和失败逐个进行WS Api调用。所以在这段时间内显示进度HUD。最后一个API的成功然后更新数据库并隐藏进度HUD。
2)如果你需要使用NSOperationQueue and NSInvocationOperation
并点击此链接。 https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift
答案 2 :(得分:0)
Api通话当然是在后台执行,但一旦通话 完成数据库更新在主线程上执行从而冻结 应用程序。
那么为什么不在单独的队列中执行呢? 尝试使用
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//your code
});
执行耗时的任务和
dispatch_async(dispatch_get_main_queue(), ^{
//your code
});
仅更新用户界面。