2009-05-21 4 views
2

В настоящее время я работаю над игрой для iPhone, и вам нужно создать анимацию на лету. Анимация основана на нескольких изображениях, и поскольку диапазон комбинаций изображений слишком велик, и невозможно предварительно создать все последовательности, я хотел бы иметь возможность пересчитывать набор изображений каждый раз, когда ситуация меняется.Утечка памяти при создании изображения

Функция создает серию изображений, которые будут использоваться в качестве последовательности анимации. Мне нужна помощь с двумя вещами:

  1. Есть несколько больших утечек памяти, которые у меня возникают проблемы с поиском - мне нужна помощь размещения их
  2. Так как я новичок в iPhone, я хочу знать, если есть это лучший способ сделать это, если у вас есть лучшее предложение о том, как писать, пожалуйста, поделитесь ...

Код:

(void) updateImages:(int) smallPicID 
{ 
    CGRect smallPicRect; 
    smallPicRect.size = CGSizeMake(25.0f, 25.0f); 

    //TODO: add smallPic location for every image. Currently the values only match the first image... 
    static const CGPoint smallPicLocation[11][SMALLPIC_LOCATION_COUNT] = 
    { 
     { {126.0f, 153.0f},{105.0f, 176.0f}, {115.0f, 205.0f}, {145.0f, 211.0f}, {166.0f, 188.0f}, {156.0f, 159.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }, 
     { {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} } 
    }; 

    for(int i = 0; i < self.m_finalImages.count; ++i) 
    { 
     // start with base image 
     UIImage * baseImg = [self.m_finalImagesEmpty objectAtIndex:i]; 
     CGImageRef baseImgCtx = baseImg.CGImage; 

     // Create the bitmap context that matches the baseImg parameters 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
     CGContextRef newImgCtx = CGBitmapContextCreate(NULL, 
                 CGImageGetWidth(baseImgCtx), 
                 CGImageGetHeight(baseImgCtx), 
                 8, 0, colorSpace, 
                 (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst)); 
     CGColorSpaceRelease(colorSpace); 

     if (newImgCtx == NULL) 
     { 
      // error creating context 
      assert(0); 
      return; 
     } 

     // Get empty drum image width, height. 
     size_t w = CGImageGetWidth(baseImgCtx); 
     size_t h = CGImageGetHeight(baseImgCtx); 
     CGRect rect = {{0,0},{w,h}}; 

     // Draw the image to the bitmap context. 
     // newImgCtx now contains the full empty drum image. 
     CGContextDrawImage(newImgCtx, rect, baseImgCtx); 

     CGContextSaveGState(newImgCtx); 
     // translate & scale because of origin difference between UIKit and CG 
     CGContextTranslateCTM(newImgCtx, 0, h); 
     CGContextScaleCTM(newImgCtx, 1, -1); 

     int startLocation = 0; 
     int endLocation = SMALLPIC_LOCATION_COUNT; 

     // for each location 
     for(int j = startLocation; j < endLocation; j++) 
     { 
      // if its empty, nothing to do, move to next bullet 
      if (m_locationStatus[j] == CY_EMPTY) 
       continue; 

      UIImage * srcImg; 
      switch (m_locationStatus[j]) 
      { 
       case CY_FULL: srcImg = [self.m_finalImagesLoaded objectAtIndex:i]; break; 
       case CY_USED: srcImg = [self.m_finalImagesSpent objectAtIndex:i]; break; 
      } 

      // create small image containing only the smallpic from the src img 
      smallPicRect.origin = smallPicLocation[i][j]; 
      CGImageRef smallpicCGImg = CGImageCreateWithImageInRect(srcImg.CGImage, smallPicRect); 

      // draw the smallpic into the new context 
      CGContextDrawImage(newImgCtx, smallPicRect, smallpicCGImg);   

      CGImageRelease(smallpicCGImg); 
     } 

     CGContextRestoreGState(newImgCtx); 

     // update the image from the context 
     UIImage *baseImg = [self.m_finalImages objectAtIndex:i]; 
     CGImageRef imgref = CGBitmapContextCreateImage(newImgCtx); 
     //[baseImg release]; 
     [baseImg initWithCGImage:imgref]; 

     CGContextRelease(newImgCtx); 
    } 
} 
+0

Вот ссылка на сайт Apple: http://discussions.apple.com/thread.jspa?threadID=1664673 – Demi

ответ

2

первые вещи, которые прыгают на меня являются создание imgref рядом конец с CGBitmapContextCreateImage(), но не соответствующие CGImageRelease(), и baseImg initWithCGImage: сообщение, которое ничего не делает, кроме жевания памяти. Я думаю, что вы хотите заменить раздел, начиная с «обновить изображение из контекста» с чем-то вроде:

CGImageRef imgref = CGBitmapContextCreateImage(newImgCtx); 
UIImage *replacmentBaseImg = [[UIImage alloc] initWithCGImage:imgref]; 
CGImageRelease(imgref); 

[self.m_finalImages replaceObjectAtIndex:i withObject:replacementBaseImg]; 
[replacementBaseImg release]; 

CGContextRelease(newImgCtx); 

Это предполагает, что m_finalImages является NSMutableArray и что вы правильно выпустили свои другие изображения, которые были вставлены в этом массиве, так что при их замене они освобождаются.

На более крупной структурной ноте вы можете посмотреть, как рисовать ваши меньшие субимазы в отдельные CALayers, а затем обменивать эти слои на экране и в разных местах, чтобы выполнить анимацию. Картирование кварца дорого, а CALayers - кешированные изображения, хранящиеся в виде текстур на графическом процессоре. Другие люди выполнили эти анимации на основе спрайтов с помощью CALayers и достигли впечатляющей производительности.