1

UIImages를 JPG로 저장하는 방법이 있는데 응용 프로그램이 다운되는 경우, 메모리가 해제되어 있다고 생각합니다. UIImageJPEGRepresentation을 사용하여 이미지를 저장하고 있으며 자동 풀링 풀에 배치하고 있지만 작동하지 않는 것 같습니다.UIImageJPEGRepresentation에 메모리 문제가 발생할 수 있습니다.

 for (Images *anImage in images) { 

      NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init]; 

      NSString *fileName = [NSString stringWithFormat:@"%@-%i-%i-%i.jpg", appDelegate.currentUserName, appDelegate.reportId, aDefect.defectId, i]; 

      [UIImageJPEGRepresentation(anImage.image, 1) writeToFile:localImagePath atomically:NO]; 

      [p drain]; 

      i++; 

     } 

위의 코드를 실행하면 분석기에서 점점 더 많은 메모리가 사용되고 있다는 것을 알게되고 결국에는 충돌이 발생합니다. 내가 줄을 제거하면 - [UIImageJPEGRepresentation (anImage.image, 1) writeToFile : localImagePath atomically : NO]; 그것은 잘 작동합니다.

FYI 루프는 NSManagedObjects 배열을 반복합니다.

도움이 될 것입니다.

- (void) convertImages { 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Report" inManagedObjectContext:context]; 
NSPredicate *predicate = [NSPredicate 
          predicateWithFormat:@"status != %@", @"Leads"]; 

[fetchRequest setEntity:entity]; 
[fetchRequest setPredicate:predicate]; 
[fetchRequest setIncludesPropertyValues:NO]; 

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 

for (Report *aReport in fetchedObjects) { 

    appDelegate.reportId = [aReport.reportId intValue]; 

    NSArray *defects = [self getAllItemDefects]; 

    for (ItemDefect *anItemDefect in defects) { 

     NSArray *defectImages = [self getImages:[anItemDefect.itemDefectId intValue] isMainImage:NO]; 

     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^(void) { 

      int i = 0; 

      for (Images *anImage in defectImages) { 

       NSString *fileName = [NSString stringWithFormat:@"%@-%i-%i-%i.jpg", appDelegate.currentUserName, [aReport.reportId intValue], [anItemDefect.itemDefectId intValue], i]; 

       NSString *localImagePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 

       [UIImageJPEGRepresentation(anImage.image, 1) writeToFile:localImagePath atomically:NO]; 

       i++; 

      } 

      dispatch_async(dispatch_get_main_queue(), ^{ 
       NSLog(@"FINISH: do eventual operations"); 
      }); 

     }); 

    } 

} 

}

나에게이 오류 제공 - - 내가 파견 내 defectImages 배열을로드하면

enter image description here

을 여기

감사

는 제안에 따라, 새로운 코드 차단, 그냥 아무것도하지 않습니다. 당신의 도움을 주셔서 감사합니다.

편집 - CoreData는 스레드로부터 안전하지 않으므로 새로운 FetchRequests 및 ObjectContexts를 사용하여 문제를 해결했습니다. 더 이상 잘못된 액세스 오류가 발생하지 않지만 메모리가 부족한 상태로 돌아 왔습니다. 내가 당신을 위해 코드를 단순화했습니다,하지만이 상태에서 메모리 누수 생산 -

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^(void) { 

      NSFetchRequest *backgroundFetchRequest = [[NSFetchRequest alloc] init]; 

      NSManagedObjectContext *backgroundContext = [[[NSManagedObjectContext alloc] init] autorelease]; 
      [backgroundContext setPersistentStoreCoordinator:persistentStoreCoordinator]; 
      NSEntityDescription *entity = [NSEntityDescription entityForName:@"Images" inManagedObjectContext:backgroundContext]; 
      NSPredicate *predicate = [NSPredicate 
             predicateWithFormat:@"itemDefectId=%i AND reportId=%i AND isMainImage=%i", itemDefectId, appDelegate.reportId, NO]; 

      [backgroundFetchRequest setEntity:entity]; 
      [backgroundFetchRequest setIncludesPropertyValues:NO]; 
      [backgroundFetchRequest setPredicate:predicate]; 

      NSArray *defectImages = [backgroundContext executeFetchRequest:backgroundFetchRequest error:&error]; 

      NSMutableArray *images = [[NSMutableArray alloc] init]; 

      for (Images *anImage in defectImages) { 
       [images addObject:anImage.image]; 
      } 

      [images release]; 

      dispatch_async(dispatch_get_main_queue(), ^{ 
       NSLog(@"FINISH: do eventual operations"); 
      }); 
     }); 
+0

"이미지"유형이 UIImage를로드하는 방법 (사용자 정의 게터가 있습니까)? –

+0

"이미지"는 NSManagedObject입니다. "images"는 executeFetchRequest 문을 통해이 루프 이전에로드되는 "Images"의 배열입니다. –

답변

0

이 좋은 해결책이 아니다를 사용 GCD :

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 

for (int i=0; i<[images count]; i++) { 

    dispatch_async(queue, ^(void) { 

     Images *anImage = (Images *)[images objectAtIndex:i]; 
     NSString *fileName = [NSString stringWithFormat:@"%@-%i-%i-%i.jpg", appDelegate.currentUserName, appDelegate.reportId, aDefect.defectId, i]; 

     [UIImageJPEGRepresentation(anImage.image, 1) writeToFile:localImagePath atomically:NO]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSLog(@"FINISH to write image %d", i); 
     }); 

    }); 
} 

또한, 코드에서, 파일 이름은 항상 동일하며 변경되지 않고 사용되지 않습니다. 코드가 부분적입니까?

그러나 비동기 프로세스의 경우 디스패처를 사용하십시오.

+0

이렇게하면 잘못된 액세스 오류가 발생합니다. 아마 "images"배열이이 코드 블록 이전에로드 되었기 때문일 것입니다. 불완전한 코드에 대한 사과, 나는 관련이없는 라인을 삭제했다. 더 이상의 단서가 있습니까? 나는 당신의 제안에 따라 다양한 변화를 만들었지 만, 모두 오류를 낳는다. –

+0

오류 및 배열 초기화 코드를 게시하십시오. –

+0

원래 메시지에 추가 –