3

代码复制自这篇博文:http: //matthewpalmer.net/blog/2014/06/21/example-ios-keychain-swift-save-query/

我曾经有这个代码:

// Search for the keychain items
let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)

// The following line crashes with an EXEC_BAD_ACCESS if dataTypeRef is nil
var opaque = dataTypeRef!.toOpaque()

当我在钥匙串查询中使用新帐户值运行上述内容时,dataTypeRefnil导致EXEC_BAD_ACCESS.

我试图通过检查是否dataTypeRefnil这样来规避这一点:

var opaque = COpaquePointer.null()
if (dataTypeRef != nil) {
    opaque = dataTypeRef!.toOpaque()    // This line should not be executed.
}

虽然调试器显示dataTypeRefnil仍然会进入 if 子句并崩溃。

谁能解释这里发生了什么?我确实有 Objective-C 的经验,但我不知道这里发生了什么。

4

1 回答 1

6

据我所知,toOpaque/fromOpaque不再需要舞蹈,您可以简单地使用可选绑定。这可以与强制转换结合NSData 使用可选链接:

let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
if let retrievedData = dataTypeRef?.takeRetainedValue() as? NSData {
    contentsOfKeychain = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
}

另请注意,这takeRetainedValue()是正确的选择,因为您“拥有”返回的项目SecItemCopyMatching(它的名称中有“复制”)。

但实际上你应该先检查返回值

let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
if status == errSecSuccess {
    if let retrievedData = dataTypeRef?.takeRetainedValue() as? NSData {
        contentsOfKeychain = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
    }
}
于 2014-10-27T19:06:14.580 回答