我正在使用MacMini进行swift开发,我正在iPhone 6S上进行测试。
我尝试安装Sqlite-wrappers(SQLite.swift,fmdb),但他们都在启动时崩溃了我的应用程序。所以我使用纯sqlite3-API。
首先,我创建了一个指向DB的指针,并将其作为静态变量提供。
static var db: OpaquePointer? = nil
.....
sqlite3_open(fileURL.path, &db)
但我有时会遇到Bad_Access崩溃。搜索网络。发现"不要在不同的线程中使用1个指针"。
所以现在我在不同的线程中使用open-statement创建一个指针,总是一个sqlite3_reset,一个finalize然后我关闭它。
static func getDBPointer() -> OpaquePointer? {
var db: OpaquePointer? = nil
if sqlite3_open(dbFile, &db) != SQLITE_OK {
print("error opening database")
} else {
print("******************* DB opened")
}
return db
}
工作好几天,没有问题,没有Bad_Access。
但现在所有数据库都表现得非常奇怪。 它运行良好一分钟,然后我无法插入或更新行,下一个语句再次正常工作。 "从表格中删除*"大多数时候都没问题,但偶尔也会失败。所有sqlite3_prepare_v2() - 语句工作正常,我看不到语法问题。 在接下来的尝试中(相同的陈述,所有信息都适当的数据)我几乎总是"准备失败......"
这是一个简短的代码示例:
let db = getDBPointer()
let insertStatementString = "INSERT INTO vorstellung_info (vorstellung_nr,datum,vorstellung,haus,autor) VALUES (\(vorst_num),\(vorst_datum),'\(vorstellung_name)','\(vorst_haus)','\(vorst_autor)');"
print("Insert vorstellung string: \(insertStatementString)")
var insertStatement: OpaquePointer? = nil
if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
if sqlite3_step(insertStatement) == SQLITE_DONE {
print("Done well.")
} else {
print("Could not insert row in vorstellung_info: \(insertStatementString)")
}
} else {
print("INSERT statement to vorstellung_info could not be prepared.")
}
sqlite3_finalize(insertStatement)
sqlite3_close_v2(db)
输出:
Insert vorstellung string: INSERT INTO vorstellung_info (vorstellung_nr,datum,vorstellung,haus,autor) VALUES (45127,1481382000000,'TEST-WantToSee','Thats the place','Interesting author');
Could not insert row in vorstellung_info: INSERT INTO vorstellung_info (vorstellung_nr,datum,vorstellung,haus,autor) VALUES (45127,1481382000000,'TEST-WantToSee','Thats the place','Interesting author');
正如我之前所说:有时甚至准备声明都失败了。
此示例的create table语句:
let createVorstellungInfo = "CREATE TABLE IF NOT EXISTS vorstellung_info(" +
"vorstellung_nr INT," +
"datum INT," +
"vorstellung TEXT," +
"haus TEXT," +
"autor TEXT);"
该计划有很多"会话"通过会话使用服务器,因此大多数非select语句在session.task或静态函数中都是异步的,由这样的任务调用。
编辑:
添加"字符串(cString:sqlite3_errmsg(db))"到任何可能的位置
"无法准备":
SELECT statement could not be prepared: SELECT * from rechnung_vorst where rechnung_nr = 9868681 AND vorstellung_nr = 45138;
-------------------------
database is locked
"无法加载"
Veranstalter could not get loaded: SELECT veranstalter_nname, veranstalter_vname, veranstalter_uid, veranstalter_ort, veranstalter_plz, veranstalter_str FROM veranstalter WHERE veranstalter_nr = 2062491;
-------------------------
unknown error
这些只是消息的两个例子。 顺便说一下:花了我4-5次尝试获取这些消息(所有这些都在一次尝试中)。首先,它工作正常,然后这些错误,然后再次工作......
答案 0 :(得分:0)
多线程SQLite很难。这非常有趣,我永远不会说你不应该试图自己解决这个挑战。但如果您想在其他地方度过时间,我建议您查看GRDB.swift。它提供了比其他库更多的并发保证:http://github.com/groue/GRDB.swift#concurrency