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

时间:2014-02-24 03:26:38

标签: ios iphone memory-leaks out-of-memory memory-pressure

幸运的是,我知道我的内存压力问题来自哪里,并且我尝试了许多技术,例如在@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型号上却不会发生。

2 个答案:

答案 0 :(得分:1)

我设法通过扩展NSOperation来解决这个问题,并在我收到数据后立即在主程序块中将其写入文件:

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

然后在这个NSOperation对象中加入了我已经拥有的NSOperationQueue。

答案 1 :(得分:0)

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

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {

NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:aPath]; 
[fileHandle seekToEndOfFile]; 
[fileHandle writeData:data]; 
[fileHandle closeFile];

}

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