7

I am getting a EXC_BAD_ACCESS (SIGBUS) on this line in my iPhone project:

if (timeoutTimer) [timeoutTimer invalidate];

The thing that has me stumped is that I don't understand how that line could crash, since the if statement is meant to be checking for nil. Am I misunderstanding the way Objective-C works, or do line numbers in crash statements sometime have the wrong line in them?

3 Answers 3

16

Just because a variable is set to a value other than nil doesn't mean it's pointing to a valid object. For example:

id object = [[NSObject alloc] init];
[object release];
NSLog(@"%@", object); // Not nil, but a deallocated object,
                      // meaning a likely crash

Your timer has probably already been gotten rid of (or possibly hasn't been created at all?) but the variable wasn't set to nil.

Sign up to request clarification or add additional context in comments.

7 Comments

makes perfect sense, thanks. I realised that I didn't retain my timer, which is something I should do.
It normally isn't necessary to retain a timer. If you create a timer with initWithFireDate..., it isn't autoreleased. And once a timer is added to a runloop (either by addTimer or one of the scheduledTimer... methods), the runloop retains it until it's finished with it.
I created it with NSTimer scheduledTimerWithTimeInterval which I assume is auto released. Is initWithFireDate considered better?
Nah, scheduledTimer... is the "normal" way to do it. But as the NSTimer Docs say: "Note in particular that run loops retain their timers, so you can release a timer after you have added it to a run loop."
Also note that [nil anySelectorYouCareToSend] is a NOP in Objective-C.
|
6

I just ran into a similar issue, so here's another example of what might cause a check such as yours to fail.

In my case, I was getting the value from a dictionary like this:

NSString *text = [dict objectForKey:@"text"];

Later on, I was using the variable like this:

if (text) {
    // do something with "text"
}

This resulted in a EXC_BAD_ACCESS error and program crash.

The problem was that my dictionary used NSNull values in cases where an object had an empty value (it had been deserialized from JSON), since NSDictionary cannot hold nil values. I ended up working around it like this:

NSString *text = [dict objectForKey:@"text"];
if ([[NSNull null] isEqual:text]) {
    text = nil;
}

1 Comment

Damn, I didn't realize NSDictionary couldn't hold Nil values. Great answer.
-1

They should be the same. Perhaps the line number is in fact incorrect.

Look for other possible errors near that in your code and see if you find anything.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.