2014-02-24 60 views
0

幸運的是,我知道我的內存壓力問題來自何處,並且我嘗試了許多技術,例如在@autorelease塊中包裝塊並將對象設置爲零,但仍然沒有成功。由於下載和保存圖像造成的內存壓力

對不起,在這裏傾銷了太多的代碼,我試圖把它削減到基本要求。下面是下載和保存圖像的代碼:

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的模型發生。

+0

你用儀器測量了代碼的內存使用情況嗎?這將告訴你分配來自哪裏,按對象類型和每個實例的分配歷史分組。您首先需要確定哪些對象導致了所有內存壓力,然後追蹤這些對象的來源以及所有用途,以瞭解如何繼續。 – bneely

+0

您要獲取的圖像的分辨率是多少?顯示器需要的最大分辨率是多少?你有沒有機會縮小圖像,以便整體處理更少的數據?您在平均應用會話中通常處理多少張圖片? – bneely

+0

正如我所看到的整個圖像先下載到緩存中,然後它會在成功塊中返回給您。如果圖像尺寸相當大,這可能是內存峯值的原因。你應該編寫你自己的操作,在裏面做請求,在NSUrlConnectionDelegate的didReceiveData方法中,你以塊的形式接收響應數據,使用NSOutputStream將該數據寫入所需的文件位置。我認爲這會解決你的問題。 –

回答

0

嘗試創建自己的類使用NSURLConnection的下載圖片,並在委託方法追加數據到您的文件只是看到下面的代碼

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

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

} 

這將幫助你在內存管理上,因爲所有的數據,下載是不需要緩存的。

+0

我明白了,但它並不適合我,也許我可能沒有正確實施它。 – dotKwame

0

我設法通過擴展的NSOperation和主塊內解決這個我收到我寫出來給文件中的數據後,立即:然後

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

此的NSOperation對象被添加一個NSOperationQueue我已經有了。

相關問題