我正在嘗試閱讀鑰匙串,但檔案警告我以下內容:
SecItemCopyMatching 會阻塞呼叫執行緒,因此如果從主執行緒呼叫它可能會導致應用程式的 UI 掛起。相反,從后臺調度佇列或異步函式呼叫 SecItemCopyMatching。
資源
所以我想寫一個在后臺運行的異步方法。
actor Keychain {
public static let standard = Keychain()
public enum Error: Swift.Error {
case failed(String)
}
public func get(_ key: String) async throws -> Data? {
let backgroundTask = Task(priority: .background) {
var query: [String: Any] = [
type(of: self).klass : kSecClassGenericPassword,
type(of: self).attrAccount : key,
type(of: self).matchLimit : kSecMatchLimitOne,
type(of: self).returnData : kCFBooleanTrue as CFBoolean
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess else {
if let errorMessage = SecCopyErrorMessageString(status, nil) {
throw Error.failed(String(errorMessage))
} else {
throw Error.failed("unsupported")
}
}
return item as? Data
}
return try await backgroundTask.value
}
}
我的問題是..演員是否已經使它成為執行緒安全的?
通常我會添加一個NSLock以確保安全。
public func get(_ key: String) async throws -> Data? {
lock.lock()
defer { lock.unlock() }
(...)
return try await task.value
}
但是現在我收到警告Instance method 'lock' is unavailable from asynchronous contexts; Use async-safe scoped locking instead; this is an error in Swift 6。
那么我如何能夠做到這一點呢?
uj5u.com熱心網友回復:
是的,演員會使其執行緒安全。不需要鎖等。請參閱 WWDC 2021 視頻使用 Swift 演員保護可變狀態。
get(_:)順便說一句,既然你已經在演員身上有了這個,你真的不需要制作async方法。演員已經在后臺執行緒上運行。所以洗掉async限定符,然后洗掉Task:
actor Keychain {
...
public func get(_ key: String) throws -> Data? {
var query: [String: Any] = [
type(of: self).klass : kSecClassGenericPassword,
type(of: self).attrAccount : key,
type(of: self).matchLimit : kSecMatchLimitOne,
type(of: self).returnData : kCFBooleanTrue as CFBoolean
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess else {
if let errorMessage = SecCopyErrorMessageString(status, nil) {
throw Error.failed(String(errorMessage))
} else {
throw Error.failed("unsupported")
}
}
return item as? Data
}
}
uj5u.com熱心網友回復:
看起來您正在使用所有區域變數(沒有實體或靜態變數),所以您應該沒問題。
uj5u.com熱心網友回復:
為什么要將 Keychain 操作放在不需要的異步塊中。沒有它你很好。鑰匙串操作是執行緒安全的,Apple 保證了這一點。請參閱本檔案。蘋果
所以不要使用 async 塊,并將所有 ui 更改放在主執行緒中(如果還沒有的話)。UI 更改需要在主執行緒中進行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/521059.html
標籤:迅速异步并发演员
上一篇:打開一個開關并關閉另外兩個
