【发布时间】:2016-12-10 20:43:03
【问题描述】:
我正在使用 MacMini 进行 swift 开发,我正在 iPhone 6S 上进行测试。
我尝试安装 Sqlite-wrappers(SQLite.swift、fmdb),但它们都在启动时使我的应用程序崩溃。所以我使用纯 sqlite3-API。
起初,我创建了一个指向数据库的指针,并将其作为静态变量提供。
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');
正如我之前所说:有时甚至准备语句也会失败。
本例的创建表语句:
let createVorstellungInfo = "CREATE TABLE IF NOT EXISTS vorstellung_info(" +
"vorstellung_nr INT," +
"datum INT," +
"vorstellung TEXT," +
"haus TEXT," +
"autor TEXT);"
程序通过会话与服务器进行大量“对话”,因此大多数非选择语句在 session.task 或由此类任务调用的静态函数中是异步的。
编辑:
将“String(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 次尝试来获取这些消息(一次尝试)。首先它工作正常,然后出现这些错误,然后它再次工作......
【问题讨论】: