这是一个简单的应用程序,从我的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];
}
}
}
如果我遗漏了任何相关信息,请告诉我。
答案 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”本身,你需要。您可能已经这样做了,但在帖子中没有包含那些代码。