2011-08-10 60 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