NSMutableArray addObject在设备上崩溃,但在模拟器上运行正常

3

我在项目中有一组像这样的图片:

enter image description here

我想把它们全部放入可变数组中,如下所示:

NSMutableArray *imageArray = [[[NSMutableArray alloc] initWithCapacity:36] retain];
for (int i = 0; i < 36; i++) {
    UIImage *image = [[UIImage imageNamed:[NSString stringWithFormat:@"quicktour_%d.JPG",i+1]] autorelease];
    [imageArray addObject:image];
}

在模拟器中运行正常,但在添加了大约5张图片后,在设备上运行时会崩溃。

这是一个非ARC项目。我查看了此处SO中所有类似的问题,并尝试了发布的解决方案,但我的问题仍然存在。

有人能帮帮我吗?

先感谢您了。

编辑:

以下是控制台输出的崩溃信息:

***** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil' * First throw call stack: (0x2f784f4b 0x39bc56af 0x2f6bec81 0x138987 0x31f2c713 0x31f2c6b3 0x31f2c691 0x31f1811f 0x31f2c107 0x31f2bdd9 0x31f26e65 0x31efc79d 0x31efafa3 0x2f750183 0x2f74f653 0x2f74de47 0x2f6b8c27 0x2f6b8a0b 0x343df283 0x31f5c049 0x1f9ab 0x3a0cdab7) libc++abi.dylib: terminating with uncaught exception of type NSException**


请问您能提供崩溃日志吗? - Mick MacCallum
请粘贴您的崩溃日志。我认为这是因为设备上的内存溢出。您正在运行时添加太多内存(请检查图像大小)。 - Pawan Rai
1
你正在过度释放图像(ImageNamed:已经返回一个自动释放的图像,不需要再次释放),并且过度保留了图像数组(init方法返回一个保留计数为+1的对象,并且不是自动释放的)。请重新阅读苹果文档中手动内存管理的规则。其他海报可能对nil问题是正确的,但这对你没有帮助,因为最终你将得到一个包含垃圾值的数组。 - Ben Pious
2个回答

3
addObject:方法接受的对象根据文档不能为空。有可能你的第五张图片命名与你请求的大小写不匹配,因此imageNamed:调用返回nil。iOS文件系统区分大小写,但OS X文件系统(通常)不区分大小写,只在设备上出现的问题通常与此事实有关。
您可以修复文件名以防止崩溃,但在将对象添加到数组之前,您应该确保您的代码检查是否为nil,以避免此类问题。

1
就是这样!天啊,我都快把头发都拔光了。非常感谢你! :) - OSMiUM

1
  1. 您确定您正在向数组中添加内容吗?
  2. 在赋值后添加一个NSLog语句,这会在设备上减慢一些速度,但是如果您未添加任何内容或添加不存在的内容,则可能崩溃。
  3. 此外,我建议再次使用NSLog来显示图像的路径,您可能会惊讶地发现图像不在正确的路径中。
  4. 现在,为了完全颠倒逻辑,尝试在启用ARC的单独项目中使用相同的代码。您是否有同样的问题?如果没有,则是内存问题,即autorelease语句,因为“autorelease”仅在autorelease池的末尾起作用,所以您可能会不断堆积图像,这并不是一个好事情。

我会将您的代码更改为:

NSMutableArray *imageArray = [[[NSMutableArray alloc] initWithCapacity:36] retain];
for (int i = 0; i < 36; i++) {
    UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"quicktour_%d.JPG",i+1]];
    [imageArray addObject:image];
    [image release];
    image = nil;
}

你的代码与 OP 的代码存在相同的问题,即如果 -imageNamed: 返回 nil,则会崩溃,如果请求的图像不可用,则会返回 nil。在添加到数组之前检查是否为 nil。 - Caleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接