2013-08-13 9 views
0

Я создаю массив изображений для UIImageView, поэтому я могу использовать метод [_myImageView startAnimating];. Я полагаю, что если я кэширую (preload), то, как это происходит, анимация бегло.Развертывание изображений, созданных с помощью UIGraphicsBeginImageContext

Но в Инструментах я вижу, что игра освобождена, но выделено слишком много памяти - я думаю, что есть некоторые фрагменты этого материала UIGraphicsBeginContext.

Я использую его правильно, есть ли другой способ, как его освободить? Спасибо заранее!

- (NSMutableArray *)generateCachedImageArrayWithFilename:(NSString *)filename extension:(NSString *)extension andImageCount:(int)count 
{ 

    _imagesArray = [[NSMutableArray alloc] init]; 
    _fileExtension = extension; 
    _animationImageName = filename; 
    _imageCount = count; 

    for (int i = 0; i < count; i++) 
    { 
     NSString *tempImageNames = [NSString stringWithFormat:@"%@%i", filename, i]; 
     NSString *imagePath = [[NSBundle mainBundle] pathForResource:tempImageNames ofType:extension]; 

     UIImage *frameImage = [self loadRetinaImageIfAvailable:imagePath]; 
     UIGraphicsBeginImageContext(frameImage.size); 
     CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height); 
     [frameImage drawInRect:rect]; 
     UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

     [_imagesArray addObject:renderedImage]; 

     if (_isDoublingFrames) 
     { 
      [_imagesArray addObject:renderedImage]; 
     } 
     else if (_isTriplingFrames) 
     { 
      [_imagesArray addObject:renderedImage]; 
      [_imagesArray addObject:renderedImage]; 
     } 

     NSLog(@"filename = %@", filename); 
    } 

    return _imagesArray; 
} 


- (UIImage *)loadRetinaImageIfAvailable:(NSString *)path 
{ 

    NSString *retinaPath = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@", [[path lastPathComponent] stringByDeletingPathExtension], [path pathExtension]]]; 

    if ([UIScreen mainScreen].scale == 2.0 && [[NSFileManager defaultManager] fileExistsAtPath:retinaPath] == YES) 
     return [[UIImage alloc] initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:retinaPath]] CGImage] scale:2.0 orientation:UIImageOrientationUp]; 
    else 
     return [UIImage imageWithContentsOfFile:path]; 
} 

-(void) dealloc 
{ 
    [_imagesArray removeAllObjects]; 
    _imagesArray = nil; 
} 

ответ

0

Я имел проблемы с памятью подобные ты написал и что я хотел бы попробовать в вашем коде

1) использовать @autoreleasepool

завернуть либо метод или содержание цикла в @autoreleasepool { } для создания локальный пул, который будет выпущен после того, как будет выполнен метод. В вашей ситуации, мне кажется оберточной петля лучше:

for (int i = 0; i < count; i++) 
    { 
    @autoreleasepool { 
    // the loop code 
    ... 
    }} 

2) убить [UIImage imageNamed]

Использование imageNamed подготовит кэш (в зависимости от размера изображения), которые никогда не будут вымываться из если вы не достигли предупреждения о памяти. Даже если вы установите myImage.image = nil, изображение все еще находится в памяти. Инструмент XCode's Intruments Allocations прекрасно покажет его. Что вы можете сделать, это инициализировать UIImage, как это, и IOS не будет кэшировать изображения:

image = [UIImage imageWithContentsOfFile:fullpath]; 

Вы можете использовать imageNamed в коде под loadRetinaImageIfAvailable.

Сохраните оба подхода, и давайте проверим это снова!

+0

Попробуй, спасибо сейчас – alexhajdu

+0

Пробовал, но он не работает. – alexhajdu