EXC_BAD_ACCESS on simple hover in Obj-C
Frequent visitor, but first post here on StackOverflow, I hope you guys can help me. I am new to Obj-C and XCode and I ran into this really ... strange ... problem. Googling found nothing. Basically, I am getting EXC_BAD_ACCESS signal on the line that does not perform dereferencing or whatever I see. Wondering if you guys don't know where to look for this. I found it work but don't know why it works ... The line of the broken version of barfs out is the line:
LevelEntity *le = entity;
where i get bad access signal.
Here:
THIS VERSION OF WORK
NSArray *contacts = [self.body getContacts];
for (PhysicsContact *contact in contacts)
{
PhysicsBody *otherBody;
if (contact.bodyA == self.body)
{
otherBody = contact.bodyB;
}
if (contact.bodyB == self.body)
{
otherBody = contact.bodyA;
}
id entity = [otherBody userData];
if (entity != nil)
{
LevelEntity *le = entity;
CGPoint point = [contact contactPointOnBody:otherBody];
}
}
THIS WORK VERSION
NSArray *contacts = [self.body getContacts];
for (NSUInteger i = 0; i < [contacts count]; i++)
{
PhysicsContact *contact = [contacts objectAtIndex:i];
PhysicsBody *otherBody;
if (contact.bodyA == self.body)
{
otherBody = contact.bodyB;
}
if (contact.bodyB == self.body)
{
otherBody = contact.bodyA;
}
id entity = [otherBody userData];
if (entity != nil)
{
LevelEntity *le = entity;
CGPoint point = [contact contactPointOnBody:otherBody];
}
}
Here, the only difference between the two examples is how I am enumerating through my array. In the first version (which works) I use for (... in ...), where, as in the second, I use for (...; ...; ...). As far as I can see, they should be the same.
This is seriously intruding on me. Does anyone have a similar experience or idea of what's going on here? It would be great:)
Cheers, Alex
a source to share
First, if you have a crash, you have a backtrace. Always provide a backtrace with your question (it will be in the debugger and can be copied / pasted).
As Vojito pointed out, the most common reason for such failures is from over-emitting objects.
In your case for(;;)
, for(... in ...)
they don't actually match. The latter probably causes objects within the array to persist for the duration of the iteration, or auto-implement after retrieval (I say "very likely" because I haven't tested it, but that would explain the behavior).
In your code, you modify the object graph during iteration using expressions like otherBody = contact.bodyB
. If any of these statements cause one of the elements in the array to be iterated out from under the array, you will see a failure. Likewise, if changing the object graph results in contact.bodyA
or contact.bodyB
becomes a dangling link, you will see a crash.
Everything is just an educated guess. Send a backtrace and, as Vojito suggested, run the Allocation tool in Tools with zombie detection enabled.
a source to share
Stack variables, including object references, will not be automatically initialized to nil / 0 / NULL. Try setting otherBody
to zero in your initializer:
PhysicsBody *otherBody = nil;
If the debugger says that the destination le
is where the exception is thrown, it might actually be a statement above it, i.e. [otherBody userData]
... No initialization, otherBody
is garbage value.
a source to share