중요한 변수에 액세스하고 상호 배타적 인 액세스가 필요하지만 완료 핸들러를 통해 반환하는 함수가 있습니다.스위프트 : 완료 처리기로 멀티 스레딩
이 내가 현재이 시도 사용하고 무엇을 :
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를 사용하며 그 안에 또 다른 완료 처리기가있어 스레드 문제가 추가됩니다.
주요 문제는 여러 스레드가 동시에 동일한 토큰을 갱신하려고 시도하고 하나의 스레드가 토큰을 갱신하면 다른 스레드는 이전 토큰을 유지하고 토큰은 갱신 만 할 수 있으므로 갱신 요청은 거부됩니다. 한 번 갱신 될 수있다.
이 시나리오를 처리하는 가장 좋은 방법은 무엇입니까?