【问题标题】:NSMutableArray addObject crashes in the device but runs in the simulator fineNSMutableArray addObject 在设备中崩溃,但在模拟器中运行良好
【发布时间】:2014-03-01 23:34:24
【问题描述】:

我的项目中有一组这样的图像,

我正在尝试将它们全部放入一个可变数组中,就像这样,

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 项目。我在这里解决了所有类似的问题,并尝试了那里发布的解决方案,但我的问题仍然存在。

谁能帮帮我?

提前致谢。

编辑:

这是崩溃时在控制台中显示的输出。

***** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“* -[__NSArrayM insertObject:atIndex:]: 对象不能为 nil' * 第一次抛出调用栈:(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:以未捕获的类型异常终止 NSException**

【问题讨论】:

  • 能否提供崩溃日志?
  • 粘贴您的崩溃日志。我认为这是因为设备上的内存溢出。您在运行时添加了这么多内存(检查图像大小)。
  • 您过度释放图像(ImageNamed:已返回自动释放图像,无需自动释放)并过度保留图像数组(初始化方法返回保留计数为 +1 的对象,并且不会自动发布)。重读 Apple 文档中手动内存管理的规则。关于 nil 问题,其他发帖者可能是正确的,但它根本不会帮助你,因为在一天结束时,你将有一个包含垃圾值的数组。

标签: ios objective-c memory-management memory-leaks nsmutablearray


【解决方案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。
【解决方案2】:

根据文档,传递给addObject: 的对象不得为零。很有可能您的第五张图片被命名为大写与您要求的不匹配,因此 imageNamed: 调用返回 nil。 iOS 文件系统区分大小写,但 OS X 文件系统(通常)不区分大小写;仅在设备上出现的问题通常与此事实有关。

您可以修复文件名以防止崩溃,但在将对象添加到数组之前,您确实应该让代码检查 nil。

【讨论】:

  • 就是这样!伙计,我正在拔头发。非常感谢! :)
猜你喜欢
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
相关资源
最近更新 更多