【问题标题】:AFURLSessionManager free memory after data uploadAFURLSessionManager 数据上传后释放内存
【发布时间】:2015-08-21 05:28:37
【问题描述】:

我正在尝试将一个大的本地文件拆分为单独的 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];
}

谢谢,托马斯

【问题讨论】:

    标签: objective-c memory nsdata afnetworking-2


    【解决方案1】:

    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 负责释放字节数据。我希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2015-11-08
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      相关资源
      最近更新 更多