Swift:带有完成处理程序的多线程
Posted
技术标签:
【中文标题】Swift:带有完成处理程序的多线程【英文标题】:Swift: Multithreading with Completion Handler 【发布时间】:2017-11-22 14:47:55 【问题描述】:我有一个访问关键变量的函数,需要互斥访问,但通过完成处理程序返回。
这是我目前用来尝试的:
static func getAccessTokenValue(completionHandlerResult : @escaping (_ accesstoken:String) -> ())
tokenQ.sync
let expire_in_str = UserDefaults.standard.value(forKey: "expires_in") as! String
print(expire_in_str)
let accessToken_time = UserDefaults.standard.value(forKey: "access_token_time") as! Date
let todayDate = Date()
let seconds = (Calendar.current as NSCalendar).components(.second, from: accessToken_time, to: todayDate, options: []).second
if seconds! < Int(5)
print("success")
completionHandlerResult( Constants.Access_Token)
else
refreshLock.wait()
self.renewAccessToken(completionHandler: accesstokenValue in
tokenQ.sync
completionHandlerResult(accesstokenValue)
)
refreshLock.signal()
目标是一次只有一个线程能够使用self.renewAccessToken
。单独使用DispatchQueue.sync
并不能实现这一点,所以我转向信号量,但上面的代码导致了死锁,因为refreshLock.signal()
似乎没有效果。
self.renewAccessToken
使用 alamofire 并在其中有另一个完成处理程序,这增加了线程问题。
我遇到的主要问题是多个线程试图同时更新同一个令牌,一旦一个线程更新令牌,其他线程保留旧令牌并且他们的更新请求被拒绝,因为令牌只能是更新一次。
处理这种情况的最佳方法是什么?
【问题讨论】:
【参考方案1】:试试这个:
static func getAccessTokenValue(completionHandlerResult : @escaping (_ accesstoken:String) -> ())
tokenQ.sync
let expire_in_str = UserDefaults.standard.value(forKey: "expires_in") as! String
let accessToken_time = UserDefaults.standard.value(forKey: "access_token_time") as! Date
let todayDate = Date()
let seconds = (Calendar.current as NSCalendar).components(.second, from: accessToken_time, to: todayDate, options: []).second
if seconds! < Int(5)
completionHandlerResult( Constants.Access_Token)
else
refreshLock.wait()
self.renewAccessToken(completionHandler: accesstokenValue in
completionHandlerResult(accesstokenValue)
)
refreshLock.signal()
【讨论】:
以上是关于Swift:带有完成处理程序的多线程的主要内容,如果未能解决你的问题,请参考以下文章