2017-05-27 32 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

相關問題