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

时间:2017-05-27 06:38:10

标签: ios multithreading sqlite

如果我执行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;
}

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

1 个答案:

答案 0 :(得分:1)

您为此使用调度队列的想法是正确的,您只是不能使用并发队列,因为这仍然并行运行块。只需使用$pdf->SetLineStyle( array( 'width' => 15, 'color' => array(0,0,0))); $pdf->Line(0,0,$pdf->getPageWidth(),0); $pdf->Line($pdf->getPageWidth(),0,$pdf->getPageWidth(),$pdf->getPageHeight()); $pdf->Line(0,$pdf->getPageHeight(),$pdf->getPageWidth(),$pdf->getPageHeight()); $pdf->Line(0,0,0,$pdf->getPageHeight()); $pdf->SetLineStyle( array( 'width' => 14, 'color' => array(255,255,255))); $pdf->Line(0,0,$pdf->getPageWidth(),0); $pdf->Line($pdf->getPageWidth(),0,$pdf->getPageWidth(),$pdf->getPageHeight()); $pdf->Line(0,$pdf->getPageHeight(),$pdf->getPageWidth(),$pdf->getPageHeight()); $pdf->Line(0,0,0,$pdf->getPageHeight()); 切换到串行队列。

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