2017-05-27 27 views
0

如果我执行sqlite3写入(插入/更新/删除)操作,我的应用程序有时会崩溃EXC_BAD_ACCESSiOS - 如何在多线程中正确执行sqlite3写入操作?

创建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; 
} 

它通过在多个线程同时写入数据似乎原因。我不知道如何处理这个问题。

+0

显示您的完整代码! – Lion

回答

1

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

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

+0

我用'sqlite3_open_v2'替换'sqlite3_open',并且现在传递'SQLITE_OPEN_FULLMUTEX'标志,它工作正常。我需要移除'dispatch_sync'操作码吗? – tomfriwel

+0

它不会伤害,所以你可以放入它,即使它不再需要。 – Sven

相关问题