在使用仪器泄漏工具分析我的应用程序时,我遇到了看不见的对象泄漏(CFRuntimeCreateInstance)。我有粗暴的想象力,泄漏发生但无法发现它:)调用树指向我的类方法从spritesheet加载图像。这是调用树的一个片段(直到泄漏对象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
答案 0 :(得分:1)
我发现了问题。在游戏开始时,我正在预加载图像。我有一个方法“loadGameResourses”循环并对单个图像加载方法“loadImageOfType ...”进行多次调用。现在,我正在单独的线程中执行“”loadGameResourses“的调用:
[self performSelectorInBackground:@selector(loadGameResourses) withObject:nil];
当我用以下内容替换它时,泄漏就消失了:
[self loadGameResourses];
我听说你需要在主线程中处理UIKit的东西,所以看起来我选择了错误的方法。使用这种适当的方法时,一切都按预期工作:
[self performSelectorOnMainThread: @selector(loadGameResourses) withObject:nil waitUntilDone: NO];
答案 1 :(得分:0)
我听说仪器的泄漏工具可以报告漏报。您是否尝试在应用运行并观看内存时打开活动监视器?如果有泄漏,内存量会越来越大。在挖得太深之前,确保你确实有泄漏。