我的iPhone应用程序中的内存泄漏在哪里?

时间:2010-11-08 21:58:45

标签: iphone memory-leaks ios

这是一个简单的应用程序,从我的Resources文件夹中获取30个图片,在NSMutableArray期间将它们放入viewDidLoad,然后根据加速度计数据更改图片。我有来自IB的UIImageView覆盖整个视图,当加速计更新其信息时,它会将uiimageview.image交换为差异图片。工作约10秒钟,然后崩溃:

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];
        }
}
}

如果我遗漏了任何相关信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

这不是由内存泄漏导致的崩溃,而是由于内存过度释放造成的。您的崩溃是由以下行引起的:

[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 alloc]返回一个有效保留计数为1的UIImage。将其添加到数组会将其增加到两个。如果您刚刚释放数组,则会导致内存泄漏。代替:

[picArr addObject:[[[UIImage alloc] initWithContentsOfFile:path]] autorelease];

这意味着你要向数组中添加一个有效保留计数为0的UIImage,它会将其提升为1,使数组成为该对象的唯一所有者。稍后当阵列消失时,大多数图像也会消失。 (imageView也将拥有分配给它的任何一个。)

不要被这些东西感到沮丧:有一天你会突然得到它并想知道为什么它会让你头痛。 :)

答案 1 :(得分:0)

这里有几个问题:

1)您没有发布要添加到“picArr”的UIImage对象。

这一行:

[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 *路径; 你在第一个循环中给路径变量一个值,所以不需要alloc + init。一旦你改变了这一点,你可以摆脱这一行:

[path release];

3)我不知道你在哪里释放“picArr”本身,你需要。您可能已经这样做了,但在帖子中没有包含那些代码。