sqlite的SWIFT是不稳定的

我已经build立了使用sqlite的swift项目。 有时,插入时实际上并没有插入正确的(或全部)值。 我知道,因为我重新启动应用程序,当我回来的条目是要么随机错误(没有插入东西)或零。 但有时是正确的。

这里是我设置的位置,是的数据在插入前的值是正确的。

let update = "INSERT INTO ToDoItem (itemName, completed, goalDate) " + "VALUES (?, ?, ?);" var statement: COpaquePointer = nil if sqlite3_prepare_v2(database, update, -1, &statement, nil) == SQLITE_OK { let itemName = item.itemName as String let completed = item.completed == true ? 1 : 0 sqlite3_bind_text(statement, 1, itemName, -1, nil) sqlite3_bind_int(statement, 2, Int32(completed)) if let goalDate = item.goalDate?.toString() { sqlite3_bind_text(statement, 3, goalDate, -1, nil) } else { sqlite3_bind_text(statement, 3, "", -1, nil) } //println("inserting \(itemName), \(completed) and \(item.goalDate?.toString())") //println("") } if sqlite3_step(statement) != SQLITE_DONE { println("error updateing table") sqlite3_close(database) return } sqlite3_finalize(statement) sqlite3_close(database) 

您可以在中间看到注释掉的println,如果没有注释掉,那么itemName有时会得到该string的一部分。

我有同样的问题。 我find了解决这个问题的方法。

 sqlite3_bind_text(statement, 1, itemName, -1, nil) --> itemName should be UTF8 String 

您应该将itemName转换为NSString,并使用UTF8String将您的string转换为UTF8。 正确的代码在这里是一样的

 let itemName = item.itemName as NSString sqlite3_bind_text(statement, 1, itemName.UTF8String, -1, nil) 

祝你好运。

这种行为实际上符合规范,错误在你的代码中。

问题的根源在你传递给sqlite3_bind_text的swift String中。 sqlite3_bind_text将文本接受为一个const char* ,它在Swift中被桥接为UnsafePointer<CChar> 。 将Swift String传递给接受UnsafePointer<CChar>的函数时的行为logging在与C API交互的“常量指针”部分中。 它说:

该string将自动转换为一个缓冲区中的UTF8,并将指向该缓冲区的指针传递给该函数。

这可能是你想要发生的事情。

它也说:

传递给函数的指针保证只在函数调用期间有效。 在函数返回之后,不要试图持久化指针并访问它。

这是你的错误的来源。 sqlite3_bind_text()事实上确实将指针保留在准备好的语句中,直到sqlite3_finalize()被调用,以便它可以在将来的sqlite3_step()调用中使用它。

另一个答案build议使用NSString.UTF8String 。 这有一个更长的一生,似乎应该是足够的。 该文件说:

这个Cstring是一个指向string对象内部结构的指针,它的生命期可能比string对象更短,并且不会有更长的生命周期。 因此,如果需要将Cstring存储在使用此属性的内存上下文之外,则应复制Cstring。

“内存上下文”在这里似乎是模糊的。 我不知道这是否意味着当前的function,或者直到当前autoreleasepool耗尽,或其他。 如果它是前两个之一,你是安全的。 如果没有,那么我会说,你仍然是安全的,因为它似乎像NSString.UTF8String已被用于这样的情况很长一段时间没有问题..