我正在使用AFNetworking下载我的应用程序用于同步解决方案的文件.在某些时候,应用程序会将一系列文件作为批处理单元下载.按照这个例子,我像这样运行批处理:
NSURL *baseURL =; AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL]; // as per: /sf/ask/17360801/ dispatch_group_t group = dispatch_group_create(); for (NSDictionary *changeSet in changeSets) { dispatch_group_enter(group); AFHTTPRequestOperation *operation = [manager POST:@"download" parameters: success:^(AFHTTPRequestOperation *operation, id responseObject) { // handle download success... // ... dispatch_group_leave(group); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // handle failure... // ... dispatch_group_leave(group); }]; [operation start]; } // Here we wait for all the requests to finish dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // run code when all files are downloaded });
这适用于批量下载.但是,我想向用户显示一个MBProgressHUD,向他们展示下载的进展情况.
AFNetworking提供了一种回调方法
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { }];
...只需将进度设置为,即可轻松更新进度表totalBytesRead / totalBytesExpectedToRead
.但是,当您同时进行多次下载时,很难总体跟踪.
我考虑NSMutableDictionary
过为每个HTTP操作设置一个密钥,使用这种通用格式:
NSMutableArray *downloadProgress = [NSMutableArray arrayWithArray:@{ @"DownloadID1" : @{ @"totalBytesRead" : @0, @"totalBytesExpected" : @100000}, @"DownloadID2" : @{ @"totalBytesRead" : @0, @"totalBytesExpected" : @200000} }];
随着每个操作的下载进行,我可以更新totalBytesRead
中心的特定操作NSMutableDictionary
- 然后总计所有totalBytesRead
和totalBytesExpected' to come up with the total for the whole batched operation. However, AFNetworking's progress callback method
downloadProgressBlock , defined as
^(NSUInteger bytesRead,long long totalBytesRead,long long totalBytesExpectedToRead){} does not include the specific operation as a callback block variable (as opposed to the
成功and
失败`回调,它确实包含特定操作作为变量,使其可访问).据我所知,这使得无法确定哪个操作专门进行回调.
有关如何使用AFNetworking跟踪多极同时下载进度的任何建议?
如果块是内联的,则可以operation
直接访问,但编译器可能会警告您循环引用.您可以通过声明弱引用并在块内使用它来解决:
__weak AFHTTPRequestOperation weakOp = operation; [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { NSURL* url = weakOp.request.URL; // sender operation's URL }];
实际上,您可以访问块内的任何内容,但是您需要了解块才能实现.通常,块中引用的任何变量在创建块时复制,即行执行的时间.这意味着我weakOp
在块中将引用行执行weakOp
时的变量值setDownloadProgressBlock
.您可以认为,如果您的块立即执行,那么您在块中引用的每个变量将是什么.