1

У меня есть метод, который экономит кучу UIImages как JPG, и мое приложение рушится, я считаю, из-за того, что память не была выпущена. Я использую UIImageJPEGRepresentation для сохранения изображений, и я обертываю его в пул автозапуска, но он, похоже, не работает.Возможная проблема с памятью на UIImageJPEGПримечание

 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"); 
      }); 

     }); 

    } 

} 

}

Это дает мне эту ошибку -

enter image description here

Если я загружаю массив defectImages в отправке блок, он просто ничего не делает. Спасибо за вашу помощь.

Редактировать - Поскольку 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. –

ответ

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

Это дает мне плохую ошибку доступа. Вероятно, потому что массив «изображений» загружается до этого блока кода. Извинения за неполный код, я удалил строки, которые не имеют отношения к делу. У вас есть еще какие-то подсказки? Я внес различные изменения, основываясь на ваших предложениях, но все это дает мне ошибки. –

+0

Отправьте свою ошибку и код инициализации массива. –

+0

Добавлено в исходное сообщение –

Смежные вопросы