2016-10-11 1 views
0

일부 이미지 (base64 문자열에서 UIImage로 변환 됨)를 다운로드하여 장치에 저장하려고하고 메모리 경고가 계속 표시됩니다.Objective-c UIImagePNGRepresentation 메모리 누수가 발생했습니다.

ontracFullScreenImageViewController *etrackDiagrams = ((ontracFullScreenImageViewController*)[viewControllerDictionary objectForKey:@"E-track Diagrams"]); 
    NSMutableSet *etrackSet = [[NSMutableSet alloc] init]; 

    for (UIImage *image in etrackDiagrams.imageArray) { 


     NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init]; 
     //convert the image to NSData and store it in the documents directory 
     NSData *pngData = UIImagePNGRepresentation(image); 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory 
     NSString * timeInMS = [NSString stringWithFormat:@"%lld", [@(floor([[NSDate date] timeIntervalSince1970] * 1000)) longLongValue]]; 
     NSString *filePath = [documentsPath stringByAppendingPathComponent:[ NSString stringWithFormat:@"%@_%@_etrack_diagram_%i_%i_image.png", delegate.userName, timeInMS, self.dataObject.dataPack.pack_id, [etrackDiagrams.imageViewArray indexOfObject:image]]]; //Add the file name 
     [pngData writeToFile:filePath atomically:YES]; 
     NSLog(@"filepath %@", filePath); 
     NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
     if ([currSysVer isEqualToString:@"5.0.1"]) { 
      [[NSURL URLWithString:filePath] setResourceValue: [NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; 
     } 
     //Add the file Path to ImageLinks 
     [etrackDiagrams.imageLinks addObject:filePath]; 
     //save the image location in Core Data 
     EtrackDiagram *etrackDiagram = [NSEntityDescription 
             insertNewObjectForEntityForName:@"EtrackDiagram" 
             inManagedObjectContext:context]; 
     etrackDiagram.locationString = filePath; 
     etrackDiagram.dataObject = dataObject; 
     [etrackSet addObject:etrackDiagram]; 
     [dataObject addEtrackDiagramsObject:etrackDiagram]; 
     [localPool drain]; 

    } 
    [dataObject addEtrackDiagrams: etrackSet]; 

이미지가 상당히 큽니다. 메모리 경고는 NSData *pngData = UIImagePNGRepresentation(image);에서 발생합니다.

불행히도 이미지의 크기를 제어 할 수는 없지만 나중에 이미지를 갤러리에 사용하려면 이미지를 장치에 저장하는 방법이 필요합니다.

코드를 @autoreleasepool으로 감싸려고했지만 아무런 차이가 없습니다.

for (UIImage *image in etrackDiagrams.imageArray) { 

이것은 당신이 메모리에 이미지의 배열을 들고 의미 :

+0

여기에 제안 된대로 @autoreleasepool로 코드를 래핑하십시오. http://stackoverflow.com/a/9779032/1689376 – alexburtnik

+0

@alex 이미 성공하지 못한 채로 시도했습니다. 그에 따라 내 질문이 업데이트되었습니다. – jampez77

답변

1

진짜 문제는이 라인입니다. 그것은 항상 위험합니다. 이 모든 이미지를 디스크에 저장하고 한 번에 하나씩 (그리고 캐싱하지 않는 방식으로) 메모리에로드해야합니다. 목표는 한 번에 최대 하나의 이미지 만 메모리에 저장하는 것입니다.

+0

여기에 좋은 점이 있습니다. 내가 한 일은 이미지를 URL에서 검색 할 때 이미지를 저장하려고 시도하는 것입니다 (개별적으로). 여전히 기쁨은 없지만 :/ – jampez77

+0

이미지를 검색 할 때 이미지가 디스크에 저장되면 왜 다시 PNG 데이터로 변환해야합니까? 그것은 데이터입니다. 그것은 구원 받았다. 그것은 경로가 있습니다. 끝난. – matt

+0

그것은 갤러리에서 사용할 수 있도록 png로 변환하는 base64 문자열입니다. – jampez77

0

매트의 이론이 잘못되었음을 증명하는 코드는 다음과 같습니다.

for(NSInteger i =0; i < etrackDiagrams.imageArray.count; i ++) { 
    UIImage *image = etrackDiagrams.imageArray[i]; 
    // here is your code to save image in device. 
} 

경우 "에 대한 (있는 UIImage * imagearray에서 이미지)"메모리에 이미지의 배열을 유지하는 것은, 다음 코드는 위의 문제를 해결하지만, 사실, 어떤 도움없이 기본적입니다.

메모리 경고는 NSData * pngData = UIImagePNGRepresentation (image)에서 발생합니다. 이미지가 꽤 큽니다. 나는이 메시지가 매우 중요하다고 생각한다 !!!

여기에 같은 문제가있는 사람이 있습니다. click here

0

어쩌면 당신은 마음 변경할 수 있습니다 : 당신이 base64로 문자열을 다운로드 할 때

  1. 이있는 NSData로 변환을 한 다음 배열에 추가;
  2. 이미지 데이터를 저장하려면 배열에서 nsdata를 선택하십시오.

일부보기에서 이미지를 표시하지 않으려면 에주의 할 필요가 없습니다. 메모리 경고가 발생합니다.

관련 문제