我的iPhone应用程序中的内存泄漏在哪里?
这是一个简单的应用程序,从我的资源文件夹获取30张图片,在viewDidLoad
期间将它们放入NSMutableArray
,然后根据加速度计数据更改图片。我有一个来自IB的UIImageView
覆盖整个视图,当加速度计更新其信息时,它将uiimageview.image
交换为差异图。作品约10秒钟,然后崩溃与此:我的iPhone应用程序中的内存泄漏在哪里?
Program received signal: “0”.
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")
在这里四处寻找后,它听起来就像是一个内存泄漏。以下是我正在使用的代码:
Interface:
{
UIAccelerometer *accel;
IBOutlet UIImageView *pic;
NSMutableArray *picArr;
}
Implementation:
- (void)viewDidLoad
{
[super viewDidLoad];
picArr = [[NSMutableArray alloc] init]; //array of pics to be used
NSString *path = [[NSString alloc] init]; //dynamic path of images to save to array
for (int i = 1; i <= 30; i++)
{
path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"];
[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]];
}
accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 0.5f;
[path release];
pic.image = [picArr objectAtIndex:15];
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
if(acceleration.y < 0.0f) //goes thru the tilted left pics
{
for (int i = 0; i <= 15; i++)
{
if(acceleration.y >= (-(15.0f-(double)i)/30.0f) && acceleration.y < (-(14.0f-(double)i)/30.0f))
{
pic.image = [picArr objectAtIndex:i+1];
}
}
}
else if(acceleration.y > 0.0f) //goes thru tilted right pics
{
for (int i = 1; i <= 14; i++)
if(acceleration.y > ((double)i/30.0f) && acceleration.y <= ((double)(i+1)/30.0f))
{
pic.image = [picArr objectAtIndex:i+15];
}
}
}
如果我遗漏了任何相关信息,请让我知道。
这不是由内存泄漏引起的崩溃,而是由内存过度释放造成的。你的崩溃是由这一行造成的:
[path release];
删除了这一行,你应该罚款。对于一些罚款的价值,无论如何;乔治所说的大部分内容也适用。
的原因是,被释放的路径将是这一个:
path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"];
这是一个对象为零的有效保留计数。虽然它有一个积极的保留计数,但它已经被自动释放,并且在您返回到主事件循环时将被释放。
你也应该删除此行:
NSString *path = [[NSString alloc] init]; //dynamic path of images to save to array
的原因是你使用它分配pathForResource的结果路径,实际上从未。当然,您需要声明路径作为变量。我建议将pathForResource行更改为:
NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"];
这是一个明智的改变,因为在循环之外没有理由需要这个。
你也应该解决这一行:
[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]];
[UIImage的页头]以1为有效保留计数它添加到一个数组将增加两个返回的UIImage。如果您稍后才发布阵列,则会导致内存泄漏。相反:
[picArr addObject:[[[UIImage alloc] initWithContentsOfFile:path]] autorelease];
这将意味着你添加的UIImage为0的有效保留计数的数组,这将其撞至1,使得数组对象的唯一所有者。之后阵列消失时,大部分图像也会消失。 (imageView也将拥有分配给它的任何一个)
不要因为这些东西而感到沮丧:有一天很快你会突然想到它,想知道为什么它会让你头痛。 :)
有一对夫妇的问题在这里:
1)您还没有释放的UIImage对象您要添加到“picArr”。
这条线:
[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]];
应该是这样的,而不是:
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
[picArr addObject: image];
[image release];
我相信你也可以这样做:
[picArr addObject: [[[UIImage alloc] initWithContentsOfFile:path] autorelease]];
2)你不需要做NSString * path = [[NSString alloc] init];你可以这样做: NSString * path; 您正在给第一个循环内的路径变量赋值,所以不需要alloc + init。一旦你改变这一点,你可以摆脱这行:
[path release];
3)我不知道你在哪里释放“picArr”本身,你需要。你可能已经在做,但没有在你的文章中包含这一点代码。
我实际上已经与 [picArr addObject:[UIImage imageWithContentsOfFile:path]]; 但也没有工作。我尝试了你所说的也没有奏效。 picArr在dealloc中获得释放,但是我将它用于程序的生命周期,所以我不想在执行期间释放它。任何其他想法? – Marty 2010-11-08 22:13:23
[picArr addObject:[UIImage imageWithContentsOfFile:path]]应该没问题。我相信[路径发布];线路会导致问题。在我提供的答案中尝试我的#2 ...只需使用NSString *路径;并停止释放“路径” – George 2010-11-08 22:17:51
我得到内存警告1和2之前,它也崩溃了。我认为它不在viewDidLoad中,因为它使它很好,直到它将足够的图片换掉。我跑了仪器(第一次使用它),似乎每次图片改变更多的记忆被采取。我以为 pic.image = [picArr objectAtIndex:i + 1] 刚刚告诉图片属性在“pic”指向数组中的图像对象。我不知道。 – Marty 2010-11-08 22:18:40
实例变量是不是属性有关系吗? – Marty 2010-11-08 23:15:07