哪个线程模式是在Swift中编译的Sqlite for iOS?

时间:2016-11-04 13:12:15

标签: ios swift sqlite

页面http://www.sqlite.org/threadsafe.html提及:

单螺纹

多线程

序列化

我们如何在Swift中实现该线程。或者如何在Swift中使用sqlite3_config(SQLITE_CONFIG_MULTITHREAD

2 个答案:

答案 0 :(得分:3)

您可以在打开数据库时添加所需的选项,而不是sqlite3_config。这仅适用于sqlite3_open_v2,不适用于sqlite3_opensqlite3_open16

以下是一个例子:

let rc = sqlite3_open_v2(databasePath, &db, SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX, nil)

答案 1 :(得分:0)

对于最终在这里寻找使用内置 SQLite3 模块调用 sqlite3_config(不管线程问题)的方法的任何人...

它不可用的原因是它使用省略号样式的可变参数参数,根据 this 不支持在 Swift 中。解决此问题的一种方法是使用包装函数创建自己的 C 头文件,以便使用您需要的任何(非可变参数)参数安排调用 sqlite3_config。

例如,类似这样的“桥接标头”涵盖了您可能需要的所有有效调用签名(就 SQLite 配置选项要求而言):

#ifndef SqliteConfig_h
#define SqliteConfig_h

#import "sqlite3.h"

static inline int sqlite3_config_no_args(int op) {
    return sqlite3_config(op);
}

static inline int sqlite3_config_ptr(int op, void* arg1) {
    return sqlite3_config(op, arg1);
}

static inline int sqlite3_config_int(int op, int arg1) {
    return sqlite3_config(op, arg1);
}

static inline int sqlite3_config_ptr_int_int(int op, void* arg1, int arg2, int arg3) {
    return sqlite3_config(op, arg1, arg2, arg3);
}

static inline int sqlite3_config_int_int(int op, int arg1, int arg2) {
    return sqlite3_config(op, arg1, arg2);
}

static inline int sqlite3_config_ptr_ptr(int op, void* arg1, void* arg2) {
    return sqlite3_config(op, arg1, arg2);
}

#endif /* SqliteConfig_h */

也许有更简洁或更惯用的方法来创建这些类型的包装器(而不是桥接头中的静态内联函数)。我不是这方面的专家。但考虑到它们只是包装调用,这似乎是一个很好的轻量级解决方法。

如果您不知道如何创建桥接头,您可以四处搜索有关桥接头的更多信息。但简而言之:您可以通过转至 Build Settings/Swift Compiler - General/Objective-C Bridging Header 并将值设置为您创建的头文件名来“手动”(在创建 .h 文件后)创建桥接头。如果您不这样做,您的 .h 文件将被忽略。或者您可以通过将一个虚拟 .c 文件拖到项目中,删除该文件,然后编辑它创建的标题来自动创建一个(无需进入编译器设置)。或者,如果您更喜欢那里的代码而不是内联代码,则使用“真正的”C 文件执行此操作。

有了这个,下面是一个使用 sqlite3_config 安装你自己的日志回调的例子:

import SQLite3

func errorLogCallback(_: OpaquePointer?, iErrCode: Int, zMsg: UnsafePointer<CChar>)
{
    let s = String(cString: zMsg)
    print("LOG:", iErrCode, s)
}

let cCallbackPtr: @convention(c) (OpaquePointer?, Int, UnsafePointer<CChar>) -> () = errorLogCallback
let rawPtr = unsafeBitCast(cCallbackPtr, to: UnsafeMutableRawPointer.self)
sqlite3_config_ptr_ptr(SQLITE_CONFIG_LOG, rawPtr, nil)