我运行在子线程中的代码,调用了AFNetworking的API来下载文件:
// targetPath是下载的临时文件路径,:app_dir/tmp/CFNetworkDownload_9z499O.tmp
NSURL* (^destinationBlock) (NSURL *targetPath, NSURLResponse *response) = ^NSURL* (NSURL *targetPath, NSURLResponse *response){
return [NSURL fileURLWithPath:localFilePath];// 下载文件最终存放地址,不同于targetPath
};
// filePath即上面那个block的返回值
void (^completionBlock) (NSURLResponse *response, NSURL *filePath, NSError *error) = ^void (NSURLResponse *response, NSURL *filePath, NSError *error){
NSLog(@"download success, file written to: %@", [filePath path]);
[[NSNotificationCenter defaultCenter] postNotificationName:RESUME_ZIP_FILE_DOWNLOAD_DONE object:self userInfo:nil];
};
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:destinationBlock completionHandler:completionBlock];
[downloadTask resume];
DEBUG才发现,completion block默认是跑在UI Thread里的。中间的过程有点复杂,其实下载确实是运行在子线程里,但是下载的文件只放在临时目录,还没移动到我指定的最终目录。所以下载刚完成,子线程后续的代码就开始跑了(都是基于下载文件已移动到最终目录的前提)。但是这个时候其实文件还不存在,要等completion block执行完,才会移动到最终目录
所以造成了一个BUG,在文件还不存在的时候,后续的逻辑就开始读取了。我的解决办法是,子线程调用下载API以后,就停止干活。completion block的最后发一个通知,原来发起调用的类,收到通知以后,再进行后续的操作:
// 创建目录,下载恢复文件
-(void) initResume
{
NSFileManager *fileManager = [NSFileManager defaultManager];
// 如果:enterpriseId/resume目录不存在,则创建
NSString *resumeDir = [YLSGlobalUtils getResumeDirPath];
if(![fileManager fileExistsAtPath:resumeDir]){
[fileManager createDirectoryAtPath:resumeDir withIntermediateDirectories:YES attributes:nil error:nil];
}
// 下载恢复zip文件
[YLSUploadHelper doDownload:[self resumeFilePath]];
}
// 响应恢复文件下载完成的事件
-(void) listenDownloadDown
{
[self performSelectorInBackground:@selector(processAfterDownloadDone) withObject:nil];
}
-(void) processAfterDownloadDone
{
// 各种逻辑
}
我感觉这种解决方式并不是很好,太依赖事件通知,系统里会有很多通知飞来飞去,而且代码也很啰嗦。后续还是需要用GCD方式来解决
分享到:
相关推荐
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"SUccess%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { ...
1.情况描述:ajax发送成功,后台也成功响应请求,并返回了json数据,通过chrome监听请求也可以看到响应的json数据,但是就是不进success方法,反而跑到error方法中了 前端: $.ajax({ type : get, data : {'dbId'...
[YBHttpTool get:url params:params cacheType:YBCacheTypeReturnCacheDataThenLoad success:^(NSDictionary *obj) { //成功 } failure:^(NSError *error) { //失败 }]; } //post请求带缓存 - (void)...
success.html file to all world !
UI跟随3d场景中的物体移动,相当于3d物体的介绍信息 https://mp.csdn.net/mp_blog/creation/success/127736844
The Measure of Success
IELTS_to_Success文本IELTS_to_Success文本IELTS_to_Success文本
Q Skills for Success Level 3 Listening and Speaking.pdf!
ThinkPHP的success并不跳转页面,而是直接输出json字符串的原因.zip 解决ThinkPHP的success并不跳转页面,而是直接输出json字符
Angular is a sophisticated technology that aims to create a framework with multi-platform ...a UI component suite that I was pretty sure would be a success similar to its predecessor.
施耐德Support as Success Factorpdf,施耐德Support as Success Factor
10 key academic skills for TOEFL IBT success 10 key academic skills for TOEFL IBT success 10 key academic skills for TOEFL IBT success 10 key academic skills for TOEFL IBT success
Laravel开发-success 打印出包裹的成功
Interview Success,PPT中内容为英文,为外教老师贡献资料,希望能对大家有所帮助
Q Skills for Success Level 2 Listening and Speaking!
success
"This is not just an important but an imperative project: to approach the problem of randomness and success using the state of the art scientific arsenal we have. Barabasi is the person." --Nassim ...