由于下载和保存图像而导致的内存压力



幸运的是,我知道我的内存压力问题来自哪里,我已经尝试了许多技术,例如将块包装在@autorelease块中并将对象设置为nil,但仍然没有成功。

很抱歉在这里转储了太多代码,我试图将其削减到要点。以下是下载和保存图像的代码:

NSMuttableArray *photosDownOps = [NSMuttableArray array];
NSURL *URL = [...];
NSURLRequest *request = [...];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFImageResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {    
    dispatch_queue_t amBgSyncQueue = dispatch_queue_create("writetoFileThread", NULL);
    dispatch_async(amBgSyncQueue, ^{
        [self savePhotoToFile:(UIImage *)responseObject usingFileName:photo.id];
    });    
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    if ([error code] !=  NSURLErrorCancelled)
        NSLog(@"Error occured downloading photos: %@", error);
}];
[photosDownOps addObject:op];
NSArray *photosDownloadOperations = [AFURLConnectionOperation batchOfRequestOperations:photosDownloadOperatons 
                                                                         progressBlock:^(NSUInteger nof, NSUInteger tno) {        
} completionBlock:^(NSArray *operations) {
    NSLog(@"all photo downloads completed");
}];
[self.photosDownloadQueue addOperations:photosDownloadOperations waitUntilFinished:NO];
+ (void) savePhotoToFile:(UIImage *)imageToSave usingFileName:(NSNumber *)photoID{
    @autoreleasepool {
        NSData * binaryImageData = UIImageJPEGRepresentation(imageToSave, 0.6);
        NSString *filePath = [Utilities fullPathForPhoto:photoID];
        [binaryImageData writeToFile:filePath atomically:YES];
        binaryImageData = nil;
        imageToSave = nil;
    }
}

这种情况虽然只发生在我测试过的iPhone 4s设备上,但在iPhone 5型号上不会发生。

我设法通过扩展 NSOperation 并在收到数据后立即将其写出到文件的主块中解决此问题:

- (void)main{
    @autoreleasepool {
        //...
        NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageUrl];        
        if (imageData) {
            NSError *error = nil;
            [imageData writeToFile:imageSavePath options:NSDataWritingAtomic error:&error];
        }
        //...
    }
}

然后,这个 NSOperation 对象被添加到我已经拥有的 NSOperationQueue 中。

尝试创建自己的类以使用 NSUrlConnection 下载映像,并在委托方法中将该数据附加到您的文件中,只需查看以下代码

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:aPath]; 
[fileHandle seekToEndOfFile]; 
[fileHandle writeData:data]; 
[fileHandle closeFile];
}

这将帮助您进行内存管理,因为下载的所有数据都不需要缓存。

最新更新