问题
I have an app I'm writing that crashes when I call addSubview on a UIScrollView with "EXC_BAD_ACCESS". It only does this on iPhone 3G in release mode and only on the device. I works fine in all these other configurations:
iPhone 3G - Debug mode iPhone 3GS - Debug AND Release Mode iPhone 4 - Debug AND Release Mode Simulator - all.
Furthermore, there is no rational reason why this should be happening. My object is not released by any of my code.
回答1:
I had the exact same problem recently, however I am not entirely sure the cause is the same. What I can tell you though is what resolved the issue for me (although I'm still not entirely satisfied with the solution).
In the end, it seems like a compiler issue, and this might confirm what others have said about compiler optimization. I am using Xcode 4.0 (build 4A304a). The issue was with LLVM compiler 2.0 Code Generation. One key in particular: "Optimization Level"
Debug was set to "None". Release was set to "Fastest, Smallest"
Changing Release to "None" fixed the crash (and similarly changing Debug to "Fastest, Smallest" caused the app the crash on launch).
回答2:
I recommend you to use NSZombieEnabled to find out what is causing a bad access to memory.
- Do you use DEBUG / RELEASE defines to branch your code?
- Do you use SDK version checkers to branch your code?
Otherwise I can't see how your app can behave diferently on different devices/configurations.
回答3:
I can propose to change optimization level of release settings to "None". I met the same problem few times (with different apps) and solved it in this way.
回答4:
I never "solved" this but I did track down the offending code. I suspect that something in this segment of Quartz code was causing a buffer overrun somewhere deep inside the core - and it only caused a problem on 3G. Some of the setup for this segment is not included but this is definitely where it is happening:
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);
回答5:
You say "My object is not released by any of my code". I've found that it's not uncommon in Objective-C to run into situations where your code has not explicitly released an object yet the object has been released all the same. For example, off the top of my head, let's say that you have an object #1 with retain count of 1 and you release it but then autorelease it accidentally. Then, before the autorelease pool is actually drained, you allocate a new object #2 -- it's not inconceivable that this new object #2 could be allocated at the same address as object #1. So when the autorelease pool is subsequently drained, it will release object #2 accidentally.
来源:https://stackoverflow.com/questions/4149960/iphone-app-crashes-only-in-release-mode-on-3g