EXC_BAD_ACCESS - NSString out of scope - crash

The app I am working on is a trivia quiz.
If you get the answer wrong, it shows you the correct answer.
The correct answer is stored in a string like so:
correctAnswer = [NSString stringWithFormat:#"1/100"];
When it's time to show the answer to the user, I set the label's text to the correct answer:
whatsRight.text = correctAnswer;
This works 99% of the time.
BUT - occasionally I get an EXC_BAD_ACCESS terminating the app and the correctAnswer string is said to be "out of scope." This seems to always happen on the same question in my app - the one shown above where the correctAnswer is 1/100. It doesn't always crash the app with EXC_BAD_ACCESS though. Lots of times it works perfectly fine, displays the answer on screen, and the app continues on. Occasionally it crashes.
Any help would be greatly appreciated!
Thanks!

Try retaining correctAnswer via [correctAnswer retain]. My thought is that the correctAnswer object may be an autorelease object and since your not retaining it, it's getting released.

Related

Facebook Connect Login Dialog crashing app

Of the many problems I've been having with my current app, this is one of the most annoying.
In the simulator the login dialog works fine, however on a device it's just a frozen white box and the console prints the following:
void SendDelegateMessage(NSInvocation*): delegate
(webView:resource:willSendRequest:redirectResponse:fromDataSource:)
failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
I've looked this up but I'm still not sure what it means.
If I try switching
[self authorizeWithFBAppAuth:NO safariAuth:NO];
to
[self authorizeWithFBAppAuth:NO safariAuth:YES];
it switches to the safari app to verify but this somehow kills my app with an error which says ReturnNotPermittedKillClient.
Has anyone experienced a similar problem? On my last app it just worked without any of these issues, and as far as I can see I've done everything the same way this time. However this project was inherited from someone else so there may be underlying causes that I am not aware of.
Edit: Just tried moving the login request from didFinishLaunchingWithOptions to a point in the intro screen class where everything else has already been loaded, just in case it was a memory issue caused by too many tasks trying to run at the same time. This time the error message didn't appear, however the login box still remained white and then closed the app a few seconds later.
Edit2: Seems like it's simply a memory error. I changed all variables which I had previously released to be retained, which has fixed the problem on my 3GS. However on my iPad 1 the problem persists. Incidentally, when changing shouldAutorotateToInterfaceOrientation from using landscaperight to using landscaperight or landscapeleft, when I rotate the iPad I get a memory warning and then the same crash. In both cases there are no debug error messages other than the memory warning, and the app just closes down - there is no breakpoint etc to see where the issue lies.
if you are using the webview then we need to do this first b4 moving to next view .delegate = nil;
This might be what you want:
There are other branches of this in NSObject in the documentation.
Code:
[self performSelector: withObject: afterDelay: ]
The problem was simply down to memory. After changing the way it loads images, sounds etc the problem has gone away.

EXC_BAD_ACCESS in main.m after converting to ARC

I have a simple UITableView application that I just converted to ARC. The conversion supposedly went fine, and the app launches now, but if I navigate into a DetailView, then try to jump back to the RootView, I get a BAD_EXC_ACCESS error in main.m, and a crash. I tried turning on Zombie objects, and that stops the crash, but I also don't get anything in the console telling me what was happening. I turned off ARC, and again, no crash, but also no more info on what was causing it in the first place.
Any ideas on how to debug this would be greatly appreciated.
BAD_EXC_ACCESS are a little tricky, mainly because they don't show up at the offending line which causes the error. Using lldb, you can use thread backtrace to get an idea of what is causing it. This answer contains a great answer with a few ideas on how to troubleshoot similar problems.

unrecognized selector sent to instance on deviceOrientationDidChange

Right now my app should only supports Portrait. On Summary/Supported Device Orientations I have only selected Portrait so I'm hoping that my app will not rotate. I was testing the app on a device and suddenly I'm getting the following error randomly:
[UIButtonContent deviceOrientationDidChange:]: unrecognized selector sent to instance
It happens when I rotate the device SOMETIMES, is not consistent, and is not always over UIBUttonContent. I supposed that if I only select Portrait, deviceOrientationDidChange should not be called or should be ignored.
Other times my app crashes with an EXC_BAD_ACCESS (code=1, address=something) but it happens when I rotate the device so I'm guessing that both errors are related.
I don't know what to do with this, it's hard to debug because I don't have feedback, the All Exceptions Breakpoint is not being called, so I don't know where and exactly why this is happening. Any idea on how to debug this is welcome.
These are the classic signs of a memory management error. You have over-released some object and it has been deallocated while something else still references it. Later, something messages it. In some cases a new object has taken its place, but that object doesn't understand the messages it's receiving. In other cases, there's no valid object and you get a crash.
Edited to second the advice to use the Zombies instrument to find the over-release.
Do you have a class that should be called with deviceOrientationDidChange:? When this happens, it usually means that you have a dangling reference to a deallocated object. You should try profiling your app with Instruments in "Zombies" mode.
I solved this issue a long time ago, but I think is good to share what actually helped me on this case.
After trying everything with no results with Instruments I started debugging old-school. I had an idea of "where" the error was so I just commented all the code on that section. I was right, the bug just disappeared along with some functionalities. After that I made "binary uncommenting" (uncomment one half) till I got the bug line. It was a third party library, I had an object that was not being released properly.

Objective-C object nil after init

Okay, I'm NOT new to Objective-C but I encountered a strange bug, that i have never seen before. Maybe I only made a small mistake and you're able to see it.
Within one of my functions I start by creating a new object from a custom view-class in the following way:
[buttonsBackground removeFromSuperview];
self.buttonsBackground = [[[PostCommentButtonsBackground alloc] initWithFrame:self.contentView.bounds] autorelease];
buttonsBackground.delegate = self;
But if I jump with the debugger over this block, the debugger claims that buttonsBackground would be a nil-pointer. But adding a NSLog right afterwards with
NSLog(#"%#",self.buttonsBackground);
still prints the line
<PostCommentButtonsBackground: 0x7bd27a0; frame = (0 0; 320 82); layer = <CALayer: 0x6e688b0>>
which clearly means, that it can't be nil. Does anybody have an idea how this can even be possible?
I am using the LLDB Debugger, not the GDB. The property buttonsBackground is declared as
#property(nonatomic, retain)PostCommentButtonsBackground *buttonsBackground;
so a missing retain isn't the case either.
EDIT: Okay, I just saw, that i'm not the only person with the exact same problem. There's another person with the same problem Debugger lldb says my object is nil when is not ?
I'm just leaving this post open anyway, because in the other post people kept claiming, the developer did a bad job with his memory management. In my post you can actually see, that this is not the case.
LLDB with the new Xcode 4.3 sometimes is totally lost, and using a NSLog instead of LLDB will show you that your initialized object is correctly initialized and not nil.
So, this is really a pain when you're in front of a bug.

Objective-C Object gone due to memory management in NSMutableArray

I have a problem regarding the memory management when adding objects to a NSMutableArray. Weird thing is that it's all working fine for the first 8 objects I add, but when adding a 9th, the application crashes when retrieving this object.
UploadStatus *status = [[UploadStatus alloc] initWithStatus:[NSString stringWithFormat:#"%#: %d", NSLocalizedString(#"uploadPictureSucceeded", #""), pic_id]
andImageInProgress:nil
imageForSuccess:nil
imageForFailed:nil];
[self.delegate notify:status];
[status release];
This is being done on several places with different texts. But this object contains my status that I display in a UITableView.
In the notify method of the delegate I add the UploadStatus object to the NSMutableArray and I reload the UITableView that shows the objects inside that array.
The first 8 times I add a UploadStatus object to the array and reload the table, it shows correctly. But the 9th time I get the error [CFString retain]: message sent to deallocated instance 0x5c655c0. This error occurs when reloading the table in the cellForRowAtIndexPath method.
Weird thing is that it always shows that the objects inside the NSMutableArray are out of scope like in this screenshot:
Nevertheless if I fetch the item, convert it into the UploadStatus class and get the status from it, it all goes smoothly (for the first 8 objects).
Does anybody have a clue why it goes wrong after adding the 9th UploadStatus object to the NSMutableArray?
Thanks a lot for your help!
The problem is with this code:
[NSString stringWithFormat:#"%#: %d", NSLocalizedString(#"uploadPictureSucceeded", #""), pic_id]
You aren't retaining the string, so it goes away on the next execution of the run loop. You're getting lucky with the first 8. They happen to not get overwritten for some reason, or possibly some other object is retaining them. But the 9th one isn't and you finally see the results of the mistake.
You need for the UploadStatus object to retain that string (and later release it).
I note that you're directly accessing your ivars in this block of code rather than using accessors. This is almost certainly the root of your problem (it is the #1 cause of memory management problems in ObjC). Switch to accessors and most of your memory management problems will go away.
You should also go ahead and run the static analyzer (Build>Analyze). It might shed light. The problem is likely not in the above code; it's somewhere that you're storing something, most likely in an an ivar.