mom*_*omo 5 asynchronous objective-c grand-central-dispatch ios
我在下面有这个逻辑; 它们基本上是3个嵌套的调度组块.
group)将执行3个短异步任务(仅从Web服务下载数据)和1个更长的异步任务:将未同步的记录上载到Web服务,在本地删除已同步的记录,最后从Web服务下载记录(首先一个包含ID和基本信息的数组,然后是这些记录中的每一个).saveGroup)是较长任务的一部分.它将等待所有未完成的记录对Web服务的请求完成.downloadGroup)将等到所有这些单个记录下载请求到服务完成.一切顺利,直到第三个派遣小组.如您所见,我获取服务器上记录的ID和基本信息,遍历数组并使用downloadGroup调用dispatch_group_enter,然后触发HTTP请求.在dispatch_group_leave完成请求时被调用.我可以看到dispatch_group_leave每个请求被调用,最后dispatch_group_notify被调用多次.
-(void) doTheSync {
dispatch_group_t group = dispatch_group_create();
[self syncFirstDataWithGroup: group];
[self syncSecondDataWithGroup: group];
[self syncThirdDataWithGroup: group];
[self syncRecordsWithExternalGroup: group];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"Finished all the sync");
});
}
-(void) syncRecordsWithExternalGroup: (dispatch_group_t) externalGroup {
dispatch_group_enter(externalGroup);
NSError* error = nil;
ConfigureDataModelHandler* configDataHandler = [ConfigureDataModelHandler sharedCoredata];
WebserviceLib* RESTClient = [WebserviceLib sharedInstance];
//get all unsynced records (f
NSArray* recordsUnsynced = [configDataHandler getAllRecordsWithSynced: NO ignoreDelete: YES withError: &error];
if (!error) {
//upload them to the BE (and mark as synced if succeed
dispatch_group_t saveGroup = dispatch_group_create();
//get full record dictionary, save and mark as synced
for (CMrecord* record in recordsUnsynced) {
NSDictionary* recordDict = [configDataHandler exportToDictionary: record.recordID.integerValue];
dispatch_group_enter(saveGroup);
[RESTClient saverecord: recordDict onComplete:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Saved unsynced record (%@) to BE", record.recordID);
//mark as synced
[configDataHandler markrecordAsSynced: record.recordID.integerValue];
dispatch_group_leave(saveGroup);
} onError:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error saving unsynced record to BE %@", error);
dispatch_group_leave(saveGroup);
}];
}
//** NOTIFY FINISH SAVING **
dispatch_group_notify(saveGroup, dispatch_get_main_queue(), ^{
NSLog(@"Finished saving all unsynced records to BE");
//delete all synced records
//TODO: Check if this makes sense. Probably better to not delete anything until we got the full record from the BE...
[configDataHandler deleteRecordsSynced];
//download small records from BE
NSString* agentNationalID = [self.coreData getLoginStatus].nationalID;
[RESTClient getRecordsForAgent: agentNationalID onComplete:^(NSInteger completeCode, NSArray *responseArray) {
NSLog(@"Success getting the records %@", responseArray);
if (completeCode == 200) {
dispatch_group_t downloadGroup = dispatch_group_create();
for (NSDictionary* shortDict in responseArray) {
dispatch_group_enter(downloadGroup);
//download full records from BE
[RESTClient getRecordByCodeAndTimestamp: shortDict onComplete:^(NSInteger completeCode, NSDictionary *responseDictionary) {
NSLog(@"Success Downloading record");
dispatch_group_leave(downloadGroup);
} onError:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error downloading record %@", shortDict);
dispatch_group_leave(downloadGroup);
}];
//** NOTIFY FINISH DOWNLOADING **
dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
NSLog(@"Finished downloading all the records");
//This is CRASHING because this block is being called as many times as the dispatch_group_leave(downloadGroup) is called
dispatch_group_leave(externalGroup);
});
}
} else {
NSLog(@"Error getting the records for Agent %@, with Code %li", @"AGENT ID", (long)completeCode);
}
} onError:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error getting the records for Agent %@, %@", @"AGENT ID", operation.response);
}];
});
}
}
Run Code Online (Sandbox Code Playgroud)
我在其他部分使用具有正常行为的调度组(创建,输入,输入,离开,离开,通知),所以我不明白这里发生了什么.它是否与嵌套块相关?关于如何dispatch_group_notify在完成时只调用一次的任何建议,或者更好的是,如何以更干净的方式实现这种嵌套的异步任务完成依赖(意味着如何等待多个请求完成,然后再激发一些并再次等待那么)?
Sam*_*ler 10
您downloadGroup每次输入时都会通知该组
for (NSDictionary* shortDict in responseArray) {
dispatch_group_enter(downloadGroup);
//download full records from BE
[RESTClient getRecordByCodeAndTimestamp: shortDict onComplete:^(NSInteger completeCode, NSDictionary *responseDictionary) {
NSLog(@"Success Downloading record");
dispatch_group_leave(downloadGroup);
} onError:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error downloading record %@", shortDict);
dispatch_group_leave(downloadGroup);
}];
// BUG IS HERE
dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
NSLog(@"Finished downloading all the records");
dispatch_group_leave(externalGroup);
});
}
// dispatch_group_notify should be moved HERE
Run Code Online (Sandbox Code Playgroud)
你只应该通知小组一次,dispatch_group_notify离开循环.
| 归档时间: |
|
| 查看次数: |
1978 次 |
| 最近记录: |