I get the error: NSArrayM was mutated while being enumerated and I've tried almost Everything I could find on stackoverflow. Keep in mind that I'm learning as I create my game :)
I'm using sprite kit and uses dispatch_async in didmovetoview to load the game.
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
// loading stuff, but also this that is causing the error:
[self buildmap];
dispatch_async(dispatch_get_main_queue(), ^(void){
// done loading
});
});
Here is the buildmap that causes the crash.
-(void)buildMap {
int intX = 0;
int intY = 0;
sqlite3_stmt *statement;
if (sqlite3_open([_databasePath UTF8String], &BlockMinerDB) == SQLITE_OK) {
NSString *sql = [NSString stringWithFormat:@"SELECT blocktype, ladder, blockreachable, walkable, zpos, texture, id, bitmask FROM map ORDER BY id DESC"];
const char *qstmt = [sql UTF8String];
if (sqlite3_prepare_v2(BlockMinerDB, qstmt, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int blockType = sqlite3_column_int(statement, 0);
int ladder = sqlite3_column_int(statement, 1);
int blockReachable = sqlite3_column_int(statement, 2);
int walkable = sqlite3_column_int(statement, 3);
int zPos = sqlite3_column_int(statement, 4);
NSString *texture = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 5)];
int idBlock = sqlite3_column_int(statement, 6);
uint32_t newBitmask = (uint32_t)[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 7)];
Blocks *testblock = [[Blocks alloc] initWithBlock:blockType blockId:idBlock ladder:ladder scene:self bitmask:newBitmask blockReachable:blockReachable walkable:walkable zPos:zPos texture:texture x:intX y:intY];
NSLog(@"%@: %i", testblock.name, blockType);
if ((blockType == 2) || (blockType == 3) || (blockType == 4) || (blockType == 5)) {
[blockArrayWalk addObject:testblock];
} else {
[blockArray addObject:testblock];
}
[background addChild:testblock];
intX++;
if (intX == 25) {
intX = 0;
intY++;
}
}
}
}
sqlite3_close(BlockMinerDB);
}
[self buildmap] uses sqlite to retreive the map from the database, i'm looping with a while loop and this is causing the crash. It loops about 20-25 times (of 600) Before crashing.
Within the loop I'm creating a new block (SKSpriteNode subclass) that places the block at an certain position with some information (position, name, physics and such, no Heavy stuff). I was using NSMutableArray to store the blocks for easy access and thought that this was the problem at first, but when I remove the [blockArray addObject:block]; the app still crashes.
If I remove every bit of code in the -(void)buildmap the app doesn't crash.
Is there something with dispatch_async and the while loop that might cause this?
I can't access the code right now but if anyone need to see more code, I can add this in about 8 hours from now ;) Would really appreciate some help, trying to solve this error for 3 weeks on and off now :D
At any point in time Sprite Kit may be enumerating over children (perhaps to draw them) and if your dispatch block then adds a new child node, it would cause the children array to mutate while being enumerated.
You could fill an array of to-be-added nodes in your dispatch block, and then after the dispatch block add them all at once.