NSArraym在枚举时发生突变,sqlite3在循环时发生突变



我得到错误:NSArrayM在枚举时发生了突变,我已经尝试了在stackoverflow上几乎所有能找到的东西。请记住,我在创建游戏时正在学习:)

我使用的是sprite工具包,并在didmovetoview中使用dispatch_async来加载游戏。

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
    });
});

这是导致崩溃的构建图。

-(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]使用sqlite从数据库中检索映射,我使用while循环进行循环,这导致了崩溃。它在撞击前绕了大约20-25圈(共600圈)。

在循环中,我创建了一个新的块(SKSpriteNode子类),它将块放置在某个位置,并提供一些信息(位置、名称、物理等等,没有沉重的东西)。我使用NSMutableArray存储块以便于访问,起初我认为这是问题所在,但当我删除[blockArray addObject:block]时;该应用程序仍然崩溃。

如果我删除-(void)buildmap中的每一个代码,应用程序就不会崩溃。

dispatch_async和while循环是否存在可能导致此问题的原因

我现在无法访问代码,但如果有人需要查看更多代码,我可以在大约8小时后添加;)非常感谢您的帮助,现在断断续续地尝试解决这个错误3周:D

在任何时间点,Sprite Kit都可能枚举子节点(可能是为了绘制它们),如果您的调度块添加了一个新的子节点,则会导致子数组在枚举时发生变化。

您可以在调度块中填充一个待添加节点的数组,然后在调度块之后一次添加所有节点。

最新更新