2

Read all of the posts regarding this error being memory related and trying to access something that is no longer there.

Problem: Error pops up at virtually random intervals. It can appear after the first enemy is killed or the Nth enemy is killed. However, it ONLY appears when an enemy is killed.

Testing: Running iOS 8 beta 5, Xcode 6 beta 5 on iPhone 5s.

Code flow:

Enemy SKNodes class instances are created at start of level and stored in NSMutableArray for reference:

Goblin *newGoblin = [[Goblin alloc] initFacingDirection:1];
// set various properties…
[enemyGoblins addObject:newGoblin];

Player’s sword makes contact with enemy:

NSMutableArray *discardedItems = [NSMutableArray array];

for(Goblin *object in enemyGoblins)
{
    [object runBloodBurst:true damagePoints:_player.swordDamage];
    if(object.goblinHealth < 0)
        [discardedItems addObject:object];
}

if([discardedItems count] > 0)
    [enemyGoblins removeObjectsInArray:discardedItems];

In the Goblin class, the “die” code is:

if(self.goblinHealth < 0)
{
    SKAction *wait0 = [SKAction waitForDuration:1.0];

    SKAction *block0 = [SKAction runBlock:^{
        [self removeActionForKey:@"animation"];
        [self runAction:[_animations goblin_dieLeft]];
    }];

    SKAction *block1 = [SKAction runBlock:^{
        [self removeFromParent];
    }];

    [self runAction:[SKAction sequence:@[block0, wait0, block1]]];

}

What I’ve tried: I disabled the “discardedItems” code because I thought ARC might dump the object from memory once the reference was lost and the subsequent Goblin class’ “die animation” would cause the crash but this did not resolve the issue. I tried zombies and breakpoints but got no useful clues either.

Am I barking up the wrong tree in regards to what I’ve tried or has anyone experienced a similar issue in Beta 5?

EDIT

Here is the backtrace:

(lldb) bt * thread #1: tid = 0x3264b, 0x000000018cb13434 SpriteKitSKCSprite::update(double) + 404, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x7000000000000018) frame #0: 0x000000018cb13434 SpriteKitSKCSprite::update(double) + 404 frame #1: 0x000000018cb13440 SpriteKitSKCSprite::update(double) + 416 frame #2: 0x000000018cb13440 SpriteKitSKCSprite::update(double) + 416 frame #3: 0x000000018cacbf28 SpriteKit-[SKScene _update:] + 140 frame #4: 0x000000018cae63f8 SpriteKit-[SKView(Private) _update:] + 568 frame #5: 0x000000018cae3a10 SpriteKit-[SKView renderCallback:] + 764 frame #6: 0x000000018cae0a9c SpriteKit__29-[SKView setUpRenderCallback]_block_invoke + 60 frame #7: 0x000000018cb0d890 SpriteKit-[SKDisplayLink _callbackForNextFrame:] + 272 frame #8: 0x000000010042ca9c libglInterpose.dylib-[DYDisplayLinkInterposer forwardDisplayLinkCallback:] + 168 frame #9: 0x000000018c615b90 QuartzCoreCA::Display::DisplayLinkItem::dispatch() + 32 frame #10: 0x000000018c615a28 QuartzCoreCA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 324 frame #11: 0x00000001897dddc0 IOKitIODispatchCalloutFromCFMessage + 376 frame #12: 0x00000001885dcf34 CoreFoundation__CFMachPortPerform + 180 frame #13: 0x00000001885f1b38 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 frame #14: 0x00000001885f1a98 CoreFoundation__CFRunLoopDoSource1 + 436 frame #15: 0x00000001885efa18 CoreFoundation__CFRunLoopRun + 1640 frame #16: 0x000000018851d664 CoreFoundationCFRunLoopRunSpecific + 396 frame #17: 0x000000019154f5a4 GraphicsServicesGSEventRunModal + 168 frame #18: 0x000000018ccd6164 UIKitUIApplicationMain + 1488 * frame #19: 0x0000000100165530 CarcerQuestmain(argc=1, argv=0x000000016fdab9d8) + 116 at main.m:16 frame #20: 0x000000019885aa08 libdyld.dylibstart + 4 (lldb)

sangony
  • 11,636
  • 4
  • 39
  • 55
  • [Understanding EXC_BAD_ACCESS](http://loufranco.com/blog/understanding-exc_bad_access) – Matias Cicero Aug 05 '14 at 14:22
  • post the call stack and exact line where error occurs, add exception breakpoint to find out – CodeSmile Aug 05 '14 at 19:40
  • @LearnCocos2D - added backtrace – sangony Aug 05 '14 at 19:57
  • @CodeMonkey - Each enemy class has a 'dead BOOL' which prevents anything else running once health is less than 0. The issue what has me scratching my head is the crash is almost random. Sometimes it happens on the 3rd enemy and sometimes on the 20th. I have added several "If(object != nil)" into my code but the crash still occurs. – sangony Aug 05 '14 at 20:15
  • What line does it crash on ? – prototypical Aug 05 '14 at 21:35
  • @prototypical - I do not know. It is not displaying a line. – sangony Aug 05 '14 at 21:50
  • Use NSLog lines to try and pinpoint where it happens, that's what I'd do first. – prototypical Aug 05 '14 at 21:54
  • @prototypical - That was the first thing I did. The crashes never seem to stay in one part of the code. – sangony Aug 05 '14 at 23:49
  • well, on a given crash, you are going to know what was the last NSLog, and that's a hint for us all. We don't know, so hard to help if you are holding back on hints for us, right ? – prototypical Aug 06 '14 at 00:45
  • also... this is iOS and Xcode Beta. So, that opens a whole other can of worms. – prototypical Aug 06 '14 at 00:47
  • @prototypical - You are right about beta being a can of worms. I do believe this is where the issue is. I appreciate your input on this. – sangony Aug 06 '14 at 02:04
  • @sangony Maybe this question can help - http://stackoverflow.com/questions/22399278/sprite-kit-ios-7-1-crash-on-removefromparent - it's not ios 8 , but has a similar SKCSprite in backtrace and is a removal issue. My guess is that something is trying to use the removed node. Do you have anything that stores a reference to these nodes ? – prototypical Aug 06 '14 at 17:50
  • @sangony I think the last comment on the linked question is an example of what I suggested in my last comment. Something of that nature might be going on. Also, turning off the showPhysics property would also be worth trying, if you have it enabled. – prototypical Aug 06 '14 at 18:09
  • @prototypical - Very interesting. It does sound very similar to what I have right now. I will try out some of the proposed solutions and see what happens. Thank you! – sangony Aug 06 '14 at 18:41
  • @prototypical - No joy. I ended up removing EVERY instance of code which could lead to an object losing a reference and I still get the same kind of errors. This is definitely a beta bug. – sangony Aug 07 '14 at 23:05
  • If you don't mind sharing the code, I'd like to take a look at it. Someone in that question was mentioning showsPhysics using SKShapeNode for the bounding boxes. Do you get this error with showsPhysics disabled ? – prototypical Aug 07 '14 at 23:48
  • @prototypical - so I think I finally isolated the pesky bug. Let me know if you are available for a chat... – sangony Aug 23 '14 at 20:35
  • my email is on my profile. Definitely interested in what the issue was. – prototypical Aug 24 '14 at 01:25
  • @prototypical - Thanks for responding. I posted the issue in my most recent question. It had to do with the calling a method containing blocks before completion. I do not know if this is an iOS 8 issue or something else. I found a workaround but still do not understand the root cause of it. – sangony Aug 24 '14 at 01:27
  • I used your code in a iOS7/XCode 5 project and I didn't get any crashes while repeatedly calling bloodBurst quickly, however I don't know what your `SKAction` definition is, so I just made a simple definition. That potentially could be the issue or not, but without seeing the `SKAction` definition can't rule it out. – prototypical Aug 24 '14 at 02:17
  • If you want to github the project, I'd take a look at it. It's hard to know if there aren't other potential causes without seeing the full picture. – prototypical Aug 24 '14 at 02:20
  • I tried it in my iOS8/Xcode6 beta with your code from the other question, and the only thing different would be the `SKAction` definition for that animation. I used just a typical `animateTextures` acton with a 60 frame animation. No crashes and no need for an ivar. – prototypical Aug 24 '14 at 03:02

3 Answers3

3

change

[self runAction:[SKAction sequence:@[block0, wait0, block1]]];

to

[self runAction:[SKAction sequence:@[block0, wait0]] completion:^{ [_self removeFromParent]; }];

I ran in to the same issue when updating IOS7 code to run on IOS8, and using the completion block fixed the issue.

A I
  • 31
  • 3
2

Reading through the comments of your question, I'm not sure if you've solved this problem, and your code snippet isn't complete enough for me to see your issue, but I recently ran into a similar problem and it took me a while to figure out, so I'd post it in case it's helpful to you or some future reader of the post.

You can see my code change here: https://github.com/ik/2048/commit/3ffec547367320c7e179624a14ac5867ed1acea2

Basically what happens is runAction is async. It is executed in the next screen refresh cycle (hence the display link call in your stack trace). So if you call removeSomething after your runAction, it can be executed before the action is run, and you will crash.

At least that's what caught me - I don't know why it never occurred in iOS 7. See code below.

- [self removeFromParentCell]; // Used to call it here - wrong.
  SKAction *wait = [SKAction waitForDuration:GSTATE.animationDuration];
  SKAction *remove = [SKAction removeFromParent];
- [self runAction:[SKAction sequence:@[wait, remove]]];
+ [self runAction:[SKAction sequence:@[wait, remove]] completion:^{
+   [self removeFromParentCell];  // This is right.
+ }];
danqing
  • 3,348
  • 2
  • 27
  • 43
0

After scouring the Apple Support Forums and running the same project on iOS 7, it appears this is a Beta release bug and not faulty code after all.

sangony
  • 11,636
  • 4
  • 39
  • 55