2

私は重要な変数にアクセスし、相互排他的なアクセスが必要ですが、完了ハンドラを介して戻ります。目標は、一度にself.renewAccessTokenを使用することができるようにする一つのスレッドだけですSwift:Completion Handlerを使用したマルチスレッド

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

これは、私は現在、これを試みるために、使用していますものです。 DispatchQueue.syncを単独で使用してもこれが達成されませんでしたので、セマフォーに移動しましたが、上記のコードではデッドロックが発生し、refreshLock.signal()は効果がありません。

self.renewAccessTokenは、alamofireを使用しており、スレッド内の問題に追加されている別の補完ハンドラがあります。

主な問題は、複数のスレッドが同じトークンを同時に更新しようとしていて、あるスレッドがトークンを更新すると、他のスレッドが古いトークンを保持し、一度更新する。

このシナリオを処理するにはどうすればよいでしょうか?

答えて

0

これを試してみてください:

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() 
     } 
    } 
} 
関連する問題