2014-10-27 53 views
3

的代碼是從這個博客帖子複製:http://matthewpalmer.net/blog/2014/06/21/example-ios-keychain-swift-save-query/相比非託管<AnyObject>爲零

我曾經有過這樣的代碼:當我運行上面的在鑰匙串查詢中使用一個新的賬戶價值

// 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() 

dataTypeRef將是nil,這導致EXEC_BAD_ACCESS

我試圖通過檢查dataTypeRefnil這樣來規避這樣的:

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

當調試器顯示,dataTypeRefnil它仍然會進入if語句和崩潰。

任何人都可以解釋這裏發生了什麼?我在Objective-C方面有經驗,但我無法弄清楚這裏發生了什麼。

回答

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) 
    } 
} 
+0

雖然我理解的意思'如果讓retrievedData = dataTypeRef .takeRetainedValue()作爲? NSData'我認爲這很醜陋。有沒有原因不使用'let retrieveData = dataTypeRef?.takeRetainedValue()as? NSData'後面加上'if nil!= retrieveData'? – Paul 2014-11-04 22:44:11

+0

@Paul:'如果讓retrieveData = ...'是一個「可選綁定」,那麼如果if塊被執行,'retrieveData'包含* unwrapped *變量。 '讓retrieveData = ...;如果nil!= retrieveData {...}'也是可能的,但是'retrieveData'是一個*可選的*,仍然必須用'!'解包:'contentsOfKeychain = NSString(data:retrieveData !, ...) '。這就是爲什麼我更喜歡第一種方法,但都適用。 – 2014-11-04 22:59:38

+0

謝謝你的澄清。爲了易讀性,我更喜歡我的版本。 – Paul 2014-11-05 06:17:09