我试图将一个大的本地文件拆分成单独的NSData部分,然后使用AFNetworking 2上传每个文件部分。在所有上传成功后,每个文件部分的数据仍在内存中。每次完成零件上传后如何释放内存?我错过了什么?
以下是代码:
-(void) uploadRequestWithPart:(FilePart*) part{
// setup request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:part.uploadURL];
[request setHTTPMethod:@"PUT"];
[request setValue:part.fileType forHTTPHeaderField:@"Content-Type"];
[request setValue:@"private" forHTTPHeaderField:@"x-amz-acl"];
if(!sessionManager) sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSProgress *progress = nil;
// create Data from file part
FILE *file = fopen([part.fileURL.path UTF8String], "rb");
if(file == NULL) return;
void *data = malloc(part.size);
fseeko(file, part.offset, SEEK_SET);
fread(data, 1, part.size, file);
fclose(file);
NSURLSessionUploadTask *upTask;
upTask = [sessionManager uploadTaskWithRequest:request fromData:[NSData dataWithBytesNoCopy:data length:part.size] progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error){
NSLog(@"%@",error.localizedDescription);
[upTask cancel]; // <- does cancelling this task release the NSData??
upTask = nil;
} else{
NSLog(@"Upload complete");
[upTask cancel]; // <- does cancelling this task release the NSData??
upTask = nil;
}
[progress removeObserver:self forKeyPath:@"partCompleted" context:nil];
}];
// setup upload progress
[progress setUserInfoObject:part forKey:@"part"];
[progress addObserver:self forKeyPath:@"partCompleted" options:NSKeyValueObservingOptionNew context:nil];
// start upload
[upTask resume];
}
谢谢,托马斯
答案 0 :(得分:0)
dataBytesNoCopy:length:在文件部分缓冲区周围创建一个NSData包装器。生成的NSData对象负责释放数据缓冲区。由于有多种方法可以从文件中获取一大块字节,我尝试了这个(这对我有用):
...
NSData *fileData = [NSData dataWithContentsOfFile:part.fileURL.path options:NSDataReadingMappedIfSafe error:nil];
NSData *partData = [fileData subdataWithRange:NSMakeRange(part.offset, part.size)];
NSURLSessionUploadTask *upTask;
upTask = [sessionManager uploadTaskWithRequest:request fromData:partData progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {...
这样ARC可以解决释放字节数据的问题。我希望这有助于某人。