我在UIImage中遇到了严重的泄漏。你能帮我吗?
-(UIImage*)getImage{
return [self getForrrrImage];
}
-(UIImage*)getForrrrImage{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
UIImage *imageResult=nil;
if(index>=0 && index<[imagesPatchs count]){
NSString *key=[imagesPatchs objectAtIndex:index];
if(small)
imageResult=[savedImagesDic objectForKey:key];
if(!imageResult){
NSRange range=[key rangeOfString:@"test_bg"];
if(range.location!=NSNotFound){
NSString *filePath1;
if(small){
NSString *str=[[NSString alloc] initWithFormat:@"%@_small",key];
filePath1=[[NSBundle mainBundle] pathForResource:str ofType:@"jpg"];
[str release];
}
else
filePath1=[[NSBundle mainBundle]pathForResource:key ofType:@"jpg"];
if(filePath1){
imageResult=[self createImageFromFile:filePath1];
if(small){
[savedImagesDic setObject:imageResult forKey:key];
}
}
}
else{
NSString *filePath;
if(small)
filePath=[[NSString alloc]initWithFormat:@"%@/%@_small.png", DOCUMENTS_FOLDER, key];
else
filePath=[[NSString alloc]initWithFormat:@"%@/%@.png", DOCUMENTS_FOLDER, key];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
imageResult=[self createImageFromFile:filePath];
if(small){
if(imageResult){
[savedImagesDic setObject:imageResult forKey:key];
[imageResult release];
}
else {
imageResult=[UIImage alloc];
}
}
else{
if(!imageResult)
imageResult=[UIImage alloc];
}
}
[filePath release];
}
}
}
else
imageResult=[UIImage alloc];
[pool drain];
return imageResult;
}
-(UIImage*)createImageFromFile:(NSString*)filePath{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
UIImage *imageResult=nil;
NSData *data=[[NSData alloc]initWithContentsOfFile:filePath options:NSUncachedRead error:nil];
imageResult=[[UIImage alloc] initWithData:data] ; ----->Heavy memory leak
[data release];
[pool drain];
return imageResult;
}
答案 0 :(得分:0)
现在,您将返回一堆自动释放和保留的对象,具体取决于所采用的代码路径。以下是解决这个问题的方法:
首先,在您的createImageFromFile:
中,您需要执行return [imageResult autorelease];
并从[imageResult release];
方法中移除getForrrrImage
。
接下来,由于您正在分配但未初始化对象,因此您有很多imageResult=[UIImage alloc];
错误。你也不自动发布它。如果您没有图像,则只需返回nil
。
请记住:你总是应该返回自动释放的对象,除了如果:
new
alloc
copy
(如mutableCopy
)在所有其他情况下,预期返回非拥有(即自动释放)对象。虽然直到现在为止只是为了让你的生活变得更轻松(以及每个使用你的代码的人),但在使用iOS 5的自动引用计数时,强制执行这些约定。所以你想确保你的代码确实如此。遵循这些规则,除非您以后喜欢大量的调试和重构。
我还认为你使用自动释放池是过度的,你应该删除它们(除非你实际调试和测量,发现它们是必要的,以防止内存警告)。无论如何,如果你想坚持使用它们,你需要这样做以保存你的对象在你返回之前不被取消分配:
[imageResult retain];
[pool drain];
[imageResult autorelease];
答案 1 :(得分:0)
只需检查每个createImageFromFile
并确保之后释放,因为你没有。
其次,您应该使用NSString的方便方法,如[NSString stringWithFormat],然后您不必每次都分配一个NString。会省你麻烦。
答案 2 :(得分:0)
您已在imageResult
和getForrrrImage
中分配了createImageFromFile
,并返回了没有匹配版本的内容。如果需要从方法返回分配的对象,则向其发送自动释放消息。
MyObject *obj = [[MyObject alloc] init];
return [obj autorelease];
请注意,您无法在方法中释放obj
,因为您需要在调用方中使用该对象。这就是使用自动释放的原因。如果您将来需要,可以在调用者中保留返回的自动释放obj
。
答案 3 :(得分:0)
而不是
[[UIImage alloc] initWithData: data];
您可以尝试
[UIImage imageWithData: data];
这样可以确保您不需要关心释放对象,因为您已经使用了为您初始化Image的类方法。
然后你也应该拍摄自动释放。像
[[[UIImage alloc] initWithData: data] autorelease]
仅作为一个例子。