iOS - 如何在多线程中正确执行 sqlite3 写入操作



如果我执行sqlite3写入(插入/更新/删除(操作,我的应用程序有时会崩溃并EXC_BAD_ACCESS

创建dispatch_queue_t

dispatch_queue_create("example.testQueue", DISPATCH_QUEUE_CONCURRENT);

-dealData: paramsarray:

- (BOOL)dealData:(NSString *)sql paramsarray:(NSArray *)params {
    __block BOOL result = NO;
    dispatch_sync(_dbQueue, ^{
        sqlite3_stmt *stmt = nil;
        //prepare
        int code = sqlite3_prepare_v2(self.sqlite, [sql UTF8String], -1, &stmt, NULL);
        if (code != SQLITE_OK) {
            NSLog(@"SQL error:%@, %@, %s", sql, params, sqlite3_errmsg((__bridge sqlite3 *)(self)));
        }
        else {
            //bind
            for (int i=0; i<params.count; i++) {
                NSString *value = safeString([params objectAtIndex:i]);
                sqlite3_bind_text(stmt, i+1, [value UTF8String], -1, SQLITE_TRANSIENT);
            }
            //step
            if(sqlite3_step(stmt) == SQLITE_ERROR) { // crash at this line
                NSLog(@"SQL step failed:%@", sql);
            }
            else {
                sqlite3_finalize(stmt);
                result = YES;
            }
        }
    });
    return result;
}

这似乎是由于在多个线程中同时写入数据。我不知道如何处理这个问题。

您为此使用调度队列的想法是正确的,您只是不能使用并发队列,因为它仍然并行运行块。只需使用 DISPATCH_QUEUE_SERIAL 切换到串行队列即可。

另一种选择是自己不关心同步,而是在打开数据库连接时传递 SQLITE_OPEN_FULLMUTEX 标志以在序列化模式下运行它。

最新更新