我有一个正在编写的应用程序,当我使用“EXC_BAD_ACCESS”在 UIScrollView 上调用 addSubview 时崩溃。它仅在 iPhone 3G 发布模式下且仅在设备上执行此操作。我在所有其他配置中都能正常工作:
iPhone 3G - 调试模式 iPhone 3GS - 调试和发布模式 iPhone 4 - 调试和发布模式模拟器 - 全部。
此外,没有合理的理由为什么会发生这种情况。我的任何代码都没有释放我的对象。
我有一个正在编写的应用程序,当我使用“EXC_BAD_ACCESS”在 UIScrollView 上调用 addSubview 时崩溃。它仅在 iPhone 3G 发布模式下且仅在设备上执行此操作。我在所有其他配置中都能正常工作:
iPhone 3G - 调试模式 iPhone 3GS - 调试和发布模式 iPhone 4 - 调试和发布模式模拟器 - 全部。
此外,没有合理的理由为什么会发生这种情况。我的任何代码都没有释放我的对象。
我最近遇到了完全相同的问题,但是我不完全确定原因是否相同。我可以告诉你的是什么为我解决了这个问题(尽管我仍然对解决方案并不完全满意)。
最后,这似乎是一个编译器问题,这可能证实了其他人关于编译器优化的说法。我正在使用 Xcode 4.0(构建 4A304a)。问题在于 LLVM 编译器 2.0 代码生成。特别是一键:“优化级别”
调试设置为“无”。发布设置为“最快,最小”
将 Release 更改为“None”修复了崩溃(同样将 Debug 更改为“Fastest, Smallest”导致应用程序在启动时崩溃)。
我建议您使用NSZombieEnabled找出导致内存访问错误的原因。
否则,我看不到您的应用在不同设备/配置上的行为方式有何不同。
我可以建议将发布设置的优化级别更改为“无”。我几次遇到同样的问题(使用不同的应用程序)并以这种方式解决了它。
你说“我的任何代码都没有释放我的对象”。我发现在 Objective-C 中遇到代码没有显式释放对象但对象已经完全释放的情况并不少见。例如,在我的脑海中,假设您有一个保留计数为 1 的对象 #1,您释放了它,但随后意外地自动释放了它。然后,在自动释放池实际耗尽之前,您分配了一个新对象#2——这个新对象#2 可以分配在与对象#1 相同的地址,这不是不可想象的。因此,当自动释放池随后被耗尽时,它会意外释放对象#2。
我从来没有“解决”这个问题,但我确实找到了有问题的代码。我怀疑这部分 Quartz 代码中的某些东西导致了内核深处某处的缓冲区溢出 - 它只在 3G 上引起了问题。此部分的一些设置不包括在内,但这绝对是它发生的地方:
gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, locations);
CGContextAddPath(context, path);
CGContextSaveGState(context);
CGContextEOClip(context);
transform = CGAffineTransformMakeRotation(1.571f);
tempPath = CGPathCreateMutable();
CGPathAddPath(tempPath, &transform, path);
pathBounds = CGPathGetPathBoundingBox(tempPath);
point = pathBounds.origin;
point2 = CGPointMake(CGRectGetMaxX(pathBounds), CGRectGetMinY(pathBounds));
transform = CGAffineTransformInvert(transform);
point = CGPointApplyAffineTransform(point, transform);
point2 = CGPointApplyAffineTransform(point2, transform);
CGPathRelease(tempPath);
CGContextDrawLinearGradient(context, gradient, point, point2, (kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation));
CGContextRestoreGState(context);
CGGradientRelease(gradient);