0
我必须上传多个文件,跟踪其进度&订阅完成&故障块才能在操作结束时显示相关消息。使用AFNetworking上传多个文件 - UIViewController不会释放
我写了我自己的AFHTTPClient包装器并创建了下面的方法。
- (void) uploadFiles:(NSArray*)files
path:(NSString*)path
parameters:(NSDictionary*)parameters
progressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block
success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure
{
NSMutableURLRequest *request =
[self multipartFormRequestWithMethod:@"POST"
path:path
parameters:parameters
constructingBodyWithBlock:
^(id <AFMultipartFormData>formData) {
for (CRLMultiPartFile *file in files) {
NSAssert(file.name, @"Name cannot be nil");
NSAssert(file.file, @"Nothing found to upload");
NSAssert(file.filename, @"FileName cannot be nil");
NSAssert(file.mimeType, @"Must set Mime-Type for %@", file.filename);
[formData appendPartWithFileData:file.file name:file.name fileName:file.filename mimeType:file.typeString];
}
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:block];
[operation setCompletionBlockWithSuccess:success failure:failure];
[self enqueueHTTPRequestOperation:operation];
}
调用此方法没有得到解除分配,并且因此所有包含的图像被保留在存储器中,以及因此导致内存泄漏和最终存储器警告视图控制器。
做的分析表明,在整个操作结束时,视图控制器具有refCount
1.
当我调用注释掉,在上传文件时,一切工作正常。
这是控制器中的代码。它使用进度模块更新用户界面上的元素。
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
ContactModel *model = (ContactModel*)[self.contacts lastObject];
[params setObject:model.phone forKey:@"receiver"];
__block typeof(self) sSelf = self;
[[JMClient sharedClient] uploadFiles:files
path:@"picture_share/"
parameters:params
progressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
CGFloat progPercent = ceilf(((CGFloat)totalBytesWritten/(CGFloat)totalBytesExpectedToWrite) * 100);
CGFloat widthToCut = (progPercent * sSelf.progWidth)/100;
CGRect frame = sSelf.progresViewBG.frame;
frame.size.width = (sSelf.progWidth - widthToCut);
frame.origin.x = (sSelf.progOrigin + widthToCut);
sSelf.progresViewBG.frame = frame;
sSelf.progLabel.text = [NSString stringWithFormat:@"%i%%", (int)progPercent];
frame = sSelf.progTipView.frame;
frame.origin.x = (sSelf.progresViewBG.frame.origin.x - frame.size.width/2);
sSelf.progTipView.frame = frame;
frame = sSelf.progLabel.frame;
frame.origin.x = (sSelf.progresViewBG.frame.origin.x - frame.size.width/2);
sSelf.progLabel.frame = frame;
} success:^(AFHTTPRequestOperation *success, id reponse) {
CGRect frame = sSelf.progresViewBG.frame;
frame.size.width = 0;
frame.origin.x = sSelf.progOrigin;
sSelf.progresViewBG.frame = frame;
[sSelf.cancelButton setImage:[UIImage imageNamed:@"trnsfr_prgss_complt.png"] forState:UIControlStateNormal];
[sSelf performSelector:@selector(hideAwayProgressBars) withObject:nil afterDelay:3];
} failure:^(AFHTTPRequestOperation *failure, NSError *error) {
[Mediator showMessage:TGLocalizedString(kMessageKeyForUploadingFailed)];
[sSelf performSelector:@selector(hideAwayProgressBars) withObject:nil afterDelay:3];
}];
self.operation = [[self.client.sharedClient.operationQueue operations] lastObject];
- (void) hideAwayProgressBars
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotifcationKeyForPhotoUploadComplete object:nil];
}
通知由父控制器接收,它从超级视图中删除此控制器的视图,并将其设置为零。
P.S. CRLMultiPartFile是一个自定义的类来保存,如果你正在使用ARC文件的属性被上传
我可以给你买啤酒吗? (thumbsup)在非ARC中,我使用了__block关键字来防止'self'在块内被捕获。在ARC中工作'__weak'。 – tGilani
为了完整起见,在ARC中,但针对iOS 5之前的版本,您可以使用'__unsafe_unretained' – newacct