简体   繁体   English

UnsafePointer 的问题<Uint8>在 Swift 的 SQLite 项目中

[英]Issue with UnsafePointer<Uint8> in SQLite project in Swift

We are implementing SQLite in iOS, in Swift, without using wrappers or Objective-C bridging.我们在 iOS 和 Swift 中实现 SQLite,不使用包装器或 Objective-C 桥接。 Everything works fine, except when doing a query and extracting the result.一切正常,除了在执行查询和提取结果时。 The issue is with the UnsafePointer<UInt8> that is returned from SQLite in Swift as follows:问题出在 Swift 中从 SQLite 返回的UnsafePointer<UInt8>如下:

var querySQL = "SELECT address, phone FROM CONTACTS WHERE NAME = 'myName'"
var cQuery = querySQL.cStringUsingEncoding(NSUTF8StringEncoding)
var statement: COpaquePointer = nil
if sqlite3_prepare_v2(contactsDB, cQuery!, -1, &statement, nil) == SQLITE_OK {
   if sqlite3_step(statement) == SQLITE_ROW {
   var address : UnsafePointer<UInt8> = sqlite3_column_text(statement, 0)
   var data = NSData(bytes: address, length: 10)
   var string = NSString(data: data, encoding: NSUTF8StringEncoding)
   println(string)

As you can see, we can convert the pointer to String if we know the length of the object (in this case 10)如您所见,如果我们知道对象的长度(在本例中为 10),我们可以将指针转换为 String

To dig into this issue, I have the following example为了深入研究这个问题,我有以下例子

let pointerFromString: UnsafePointer<Int8> = "xyz".cStringUsingEncoding(NSUTF8StringEncoding)
let stringFromPointer = String.fromCString(anotherPointerFromString_Int8)                    println(stringFromPointer!)

Given that CChar is an alias of Int8 , I can convert a String to UnsafePointer<Int8> using .cStringUsingEncoding() , and then back to String using .fromCString(<UnsafePointer_CChar>)鉴于CChar是的别名Int8 ,我可以一个转换StringUnsafePointer<Int8>使用.cStringUsingEncoding()然后再返回到String使用.fromCString(<UnsafePointer_CChar>)

The problem is that my SQLite result is a UnsafePointer_UInt8 , that can´t be used with .fromCString()问题是我的 SQLite 结果是UnsafePointer_UInt8 ,不能与.fromCString()一起使用

The bottom line question is: Is it possible to convert or cast a UnsafePointer_UInt8 to UnsafePointer_Int8底线问题是:是否可以将UnsafePointer_UInt8转换或转换为UnsafePointer_Int8

This should work:这应该有效:

let address = sqlite3_column_text(statement, 0)
let string = String.fromCString(UnsafePointer<CChar>(address))

Update for Swift 3 (Xcode 8), compare Swift 3: convert a null-terminated UnsafePointer<UInt8> to a string :更新 Swift 3 (Xcode 8),比较Swift 3:convert a null-terminated UnsafePointer<UInt8> to a string

let string = String(cString: sqlite3_column_text(statement, 0))

Update:更新:

sqlite3_column_text() returns an implicitly unwrapped optional, and that is why you can pass it to String(cString:) directly. sqlite3_column_text()返回一个隐式解包的可选项,这就是您可以直接将它传递给String(cString:)

But according to Column methods, error and NULL handling #41 , the return value can be null (in an out-of-memory situation, or if called with a NULL column type).但是根据Column 方法、错误和 NULL 处理 #41 ,返回值可以是 null(在内存不足的情况下,或者如果使用 NULL 列类型调用)。 Therefore it is safer to do因此,这样做更安全

if let text = sqlite3_column_text(statement, 0) {
    let string = String(cString: text)
    // ...
} else {
    // sqlite3_column_text() returned NULL
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM