Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error when attempting to remove node from parent using fast enumeration

After Upgrading to iOS 8 b3 and Xcode 6 b3 I get an error in the didSimulatePhysics method:

[self enumerateChildNodesWithName:@"name" usingBlock:^(SKNode *node, BOOL *stop) {
    if (node.position.y < 0 || node.position.x>320 || node.position.x<0) {
        [node removeFromParent];
    }
}];

Although I have exception breakpoint enabled and zombie objects I have no further info of why this is happening. The error is Thread 1 BreakPoint 1.3. [level didSimulatePhysics] Any help is much appreciated.

Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7edf17d0> was mutated while being enumerated.'
like image 867
snksnk Avatar asked Jul 08 '14 07:07

snksnk


1 Answers

Behavior may change between iOS versions. It may have actually crashed at some point or very rarely even in Xcode 5, you just didn't get to see it.

The problem is easily circumvented by delaying the execution of the removeFromParent method. This should do the trick because actions are evaluated at a specific point in the game loop rather than instantaneously:

[self enumerateChildNodesWithName:@"name" usingBlock:^(SKNode *node, BOOL *stop) {
    if (node.position.y < 0 || node.position.x>320 || node.position.x<0) {
        [node runAction:[SKAction removeFromParent]];
    }
}];

If this won't work use the "old trick": filling an NSMutableArray with to-be-deleted items and removing the nodes in that array after enumeration:

NSMutableArray* toBeDeleted = [NSMutableArray array];

[self enumerateChildNodesWithName:@"name" usingBlock:^(SKNode *node, BOOL *stop) {
    if (node.position.y < 0 || node.position.x>320 || node.position.x<0) {
        [toBeDeleted addObject:node];
    }
}];

for (CCNode* node in toBeDeleted)
{
    [node removeFromParent];
}
like image 82
LearnCocos2D Avatar answered Nov 14 '22 23:11

LearnCocos2D