Как исправить утечку объекта CFRuntimeCreateInstance? - PullRequest
1 голос
/ 11 августа 2011

У меня возникла невидимая утечка объектов (CFRuntimeCreateInstance) при профилировании моего приложения с помощью инструмента утечки инструментов.Я плохо представляю себе, где происходит утечка, но не могу ее обнаружить :) Дерево вызовов указывает мне на мой метод класса для загрузки изображения из таблицы спрайтов.Вот фрагмент дерева вызовов (до утечки объекта CFRuntimeCreateInstance):

+[ImageCache loadImageOfType:andIndex:]
 +[NSString stringWithFormat:]
  _CFStringCreateWithFormatAndArgumentsAux
   CFStringCreateCopy
    __CFStringCreateImmutableFunnel3
     _CFRuntimeCreateInstance

Я использую этот метод вспомогательного класса для загрузки и кэширования изображения.Метод использует статический NSMutableDictionary, где он загружает загруженное изображение для дальнейшего использования.Мои изображения сгруппированы в спрайт-листы, поэтому метод считывает соответствующий файл изображения и считывает соответствующую область изображения.Вот мой метод:

+(UIImage*)loadImageOfType:(int)type andIndex:(int)index{
  UIImage *image;

  if (!dict) dict = [[NSMutableDictionary dictionary] retain];

  //First, trying to get already loaded image
  int ind = IMAGECOUNT * type + index; //calculating the index that is used for storing image in dict
  image = [dict objectForKey:[NSString stringWithFormat:@"%d", ind]]; //trying to get image
  if (!image){ //if image is not loaded then read the spriteimage file 
    NSString *spritesheetName = [NSString stringWithFormat:@"itemsprite%d.png", type];
    NSString* imagePath = [[NSBundle mainBundle] pathForResource:spritesheetName ofType:nil];
    image = [UIImage imageWithContentsOfFile:imagePath];
    if (image) //if spritesheet exists
    {
        int loopInd; 
        CGFloat x = 0, y = 0;
        //load all images from it
        for (int i=0; i<IMAGECOUNT; i++) {
            UIImage *img;
            loopInd = IMAGECOUNT * type + i;
            CGImageRef imageRef = CGImageCreateWithImageInRect( [image CGImage], CGRectMake(x, y, ITEMIMAGESIZE, ITEMIMAGESIZE)); 
            img = [UIImage imageWithCGImage:imageRef];
            [dict setObject:img forKey:[NSString stringWithFormat:@"%d", loopInd]];
            CGImageRelease(imageRef);
            x += ITEMIMAGESIZE;
        }
    }
    //set image var to be image needed
    image = [dict objectForKey:[NSString stringWithFormat:@"%d", ind]];
  }    

  return image;   
}

Любые предложения, с чего начать?

ОБНОВЛЕНИЕ: У меня также много сообщений в области отладки, все они очень похожи:

__NSAutoreleaseNoPool(): Object 0x4c55e80 of class NSCFNumber autoreleased with no pool in place - just leaking

__NSAutoreleaseNoPool(): Object 0x4c69060 of class __NSCFDictionary autoreleased with no pool in place - just leaking

__NSAutoreleaseNoPool(): Object 0x4c6a620 of class NSCFString autoreleased with no pool in place - just leaking

__NSAutoreleaseNoPool(): Object 0x4e75fe0 of class NSPathStore2 autoreleased with no pool in place - just leaking

__NSAutoreleaseNoPool(): Object 0x4e312d0 of class UIImage autoreleased with no pool in place - just leaking

Ответы [ 2 ]

1 голос
/ 11 августа 2011

Я нашел проблему. В начале игры я предварительно загружаю изображения. У меня есть метод «loadGameResourses», который зацикливается и выполняет несколько вызовов одного метода загрузки изображения «loadImageOfType ...». Сейчас я выполняю вызов "" loadGameResourses "в отдельном потоке:

[self performSelectorInBackground:@selector(loadGameResourses) withObject:nil]; 

Утечки просто исчезли, когда я заменил это на:

[self loadGameResourses];

Я слышал, что вам нужно разобраться с UIKit в основном потоке, так что, похоже, я выбрал неправильный метод. Все работает, как и ожидалось, при использовании этого соответствующего метода:

[self performSelectorOnMainThread: @selector(loadGameResourses) withObject:nil waitUntilDone: NO]; 
0 голосов
/ 11 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...