2011-08-10 48 views
1

当使用仪器泄漏工具对我的应用程序进行分析时,我遇到了看不见的对象泄漏(CFRuntimeCreateInstance)。我有粗略的想象力发生泄漏,但无法发现它:)调用树指向我的类方法从spritesheet加载图像。这里是调用树的片段(直到泄漏对象CFRuntimeCreateInstance):如何修复CFRuntimeCreateInstance对象泄漏?

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

我使用加载这个辅助类的方法和缓存图像。该方法使用静态NSMutableDictionary,其中它推动加载的图像以供进一步使用。我的图像被分组为spritesheets,所以该方法读取相应的图像文件并读取相应的图像区域。这里是我的方法:

+(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 

回答

1

我发现了这个问题。在比赛开始时,我正在预加载图像。我有一个方法“loadGameResourses”循环并对单个图像加载方法“loadImageOfType ...”进行多个调用。现在,我执行的单独的线程“” loadGameResourses”的号召:

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

的泄漏就这样消失了,当我更换了与:

[self loadGameResourses]; 

我听说你需要处理的UIKit东西在主线程,所以它看起来像我选择了错误的方法,一切正常使用该适当的方法时,如期望的那样。

[self performSelectorOnMainThread: @selector(loadGameResourses) withObject:nil waitUntilDone: NO]; 
0

我听说仪器的泄漏工具可以报告虚假泄漏。您是否尝试在应用程序运行并观看内存时打开Activity Monitor?如果泄漏,内存的数量会越来越大。确保在挖得太深之前确实有泄漏。

+0

看一看底部后更新我已经通过观察我的应用程序活动监视器,它变得越来越大。确实有多处泄漏,我的方法有些问题:( – Centurion