I have 100 images in my resource bundle named like image1.jpg,image2.jpg. Basically what i am trying to do is create path names to those images dynamically inside a for loop.
While testing in simulator,the images loaded fine and the app did not crash.But while testing the app with instruments i was shocked to see the heavy memory leak that was happening while i was creating the path1 object.
我的资源包中有100幅图片,比如image1.jpg、image2.jpg。基本上我要做的就是在for循环中动态创建这些图像的路径名。在模拟器中测试时,图像加载良好,应用程序没有崩溃。但当我用仪器测试这款应用时,我震惊地看到在我创建path1对象时发生了严重的内存泄漏。
I am pasting the entire method here for reference
- (id)init {
self = [super init];
if (self) {
self.arrayImages = [[[NSMutableArray alloc] init] autorelease];
for(int i=1 ; i<100 ; i++){
NSString *str = [NSString stringWithFormat:@"Century%d",i];
NSString *path1 = [[NSBundle mainBundle] pathForResource:str ofType:@"jpg"];
[self.arrayImages addObject:path1];
}
}
return self;
}
}
As i have not made use of any alloc inside the loop i dont have any ownership and hence no right to release the object.What is the reason for this memory leak??
由于我没有在循环中使用任何alloc,我没有任何所有权,因此也没有释放对象的权利。内存泄漏的原因是什么?
Kindly explain the problem and provide the necessary solution in order to fix it..
请解释问题,并提供必要的解决方案。
As always,any help is highly appreciated..
一如既往,我们非常感谢您的帮助。
3 个解决方案
#1
3
arrayImages
is retaining path1
, and so if you do not release arrayImages
it will leak. How are you creating arrayImages
, and are you releasing it anywhere?
arrayImages保留了path1,因此如果不释放arrayimage,它将会泄漏。你是如何创建arrayImages的,你在哪里发布它?
Edited based on comments:
编辑基于评论:
Make sure you release arrayImages
in your -dealloc
method like so: [arrayImages release];
(note the lack of self
).
确保在-dealloc方法中释放arrayImages,比如:[arrayImages释放];(注意缺乏自我)。
#2
2
There is no leak in the code you've shown.
您所显示的代码没有漏洞。
There are (at least) two possibilities:
(至少)有两种可能性:
- You have a leak in code you didn't paste into your question
- 你有一个代码漏洞,你没有粘贴到你的问题
- Everything is fine and Instruments gave you a false-positive
- 一切都很好,仪器给你一个假阳性
Your loop will create a lot of autoreleased variables. These won't be deallocated until after the loop has finished, but that's how it's supposed to work.
您的循环将创建许多自定义变量。在循环完成之后,这些将不会被释放,但这是它应该工作的方式。
#3
-1
The reason for the leak would be this line right here:
泄露的原因是这条线:
NSString *str = [NSString stringWithFormat:@"Century%d",i];
By using convenience methods in Objective-C, what happens in the background is the following:
使用Objective-C中的便利方法,在后台发生的情况如下:
NSString *str = [[[NSString alloc] initWithFormat:@"Century%d", i] autorelease];
Not using alloc/init to create a weak reference is a misconception. You are always the owner of a created object, no matter how you create it. The convenience method simply does the alloc/init and autoreleases it for you.
不使用alloc/init创建弱引用是一种误解。无论如何创建,您始终是已创建对象的所有者。便利的方法只是做alloc/init,并自动为您发送。
Here's what I would suggest you do to avoid leaking memory:
为了避免内存泄漏,我建议你这样做:
- (id)init {
self = [super init];
if (self) {
self.arrayImages = [[[NSMutableArray alloc] init] autorelease];
NSAutoreleasePool *tmpPool = [[NSAutoreleasePool alloc] init];
for(int i = 1 ; i < 100 ; i++) {
NSString *str = [NSString stringWithFormat:@"Century%d",i];
NSString *path1 = [[NSString alloc] initWithString:[[NSBundle mainBundle] pathForResource:str ofType:@"jpg"]];
[self.arrayImages addObject:path1];
[path1 release];
}
[tmpPool drain];
}
return self;
}
Let me know if this works better for you.
如果这样对你更好的话,请告诉我。
-EDIT- Allocating the path1 object and releasing it after adding to arrayImages.
-编辑-分配path1对象并在添加到arrayImages后释放它。
#1
3
arrayImages
is retaining path1
, and so if you do not release arrayImages
it will leak. How are you creating arrayImages
, and are you releasing it anywhere?
arrayImages保留了path1,因此如果不释放arrayimage,它将会泄漏。你是如何创建arrayImages的,你在哪里发布它?
Edited based on comments:
编辑基于评论:
Make sure you release arrayImages
in your -dealloc
method like so: [arrayImages release];
(note the lack of self
).
确保在-dealloc方法中释放arrayImages,比如:[arrayImages释放];(注意缺乏自我)。
#2
2
There is no leak in the code you've shown.
您所显示的代码没有漏洞。
There are (at least) two possibilities:
(至少)有两种可能性:
- You have a leak in code you didn't paste into your question
- 你有一个代码漏洞,你没有粘贴到你的问题
- Everything is fine and Instruments gave you a false-positive
- 一切都很好,仪器给你一个假阳性
Your loop will create a lot of autoreleased variables. These won't be deallocated until after the loop has finished, but that's how it's supposed to work.
您的循环将创建许多自定义变量。在循环完成之后,这些将不会被释放,但这是它应该工作的方式。
#3
-1
The reason for the leak would be this line right here:
泄露的原因是这条线:
NSString *str = [NSString stringWithFormat:@"Century%d",i];
By using convenience methods in Objective-C, what happens in the background is the following:
使用Objective-C中的便利方法,在后台发生的情况如下:
NSString *str = [[[NSString alloc] initWithFormat:@"Century%d", i] autorelease];
Not using alloc/init to create a weak reference is a misconception. You are always the owner of a created object, no matter how you create it. The convenience method simply does the alloc/init and autoreleases it for you.
不使用alloc/init创建弱引用是一种误解。无论如何创建,您始终是已创建对象的所有者。便利的方法只是做alloc/init,并自动为您发送。
Here's what I would suggest you do to avoid leaking memory:
为了避免内存泄漏,我建议你这样做:
- (id)init {
self = [super init];
if (self) {
self.arrayImages = [[[NSMutableArray alloc] init] autorelease];
NSAutoreleasePool *tmpPool = [[NSAutoreleasePool alloc] init];
for(int i = 1 ; i < 100 ; i++) {
NSString *str = [NSString stringWithFormat:@"Century%d",i];
NSString *path1 = [[NSString alloc] initWithString:[[NSBundle mainBundle] pathForResource:str ofType:@"jpg"]];
[self.arrayImages addObject:path1];
[path1 release];
}
[tmpPool drain];
}
return self;
}
Let me know if this works better for you.
如果这样对你更好的话,请告诉我。
-EDIT- Allocating the path1 object and releasing it after adding to arrayImages.
-编辑-分配path1对象并在添加到arrayImages后释放它。