简体   繁体   English

RequestRetrier Alamofire锁不起作用

[英]RequestRetrier Alamofire lock not working

I'm implementing a RequestRetrier with Alamofire to refresh the accessToken of a given user. 我正在用Alamofire实现RequestRetrier,以刷新给定用户的accessToken。

func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
    lock.lock() ; defer { lock.unlock() }

    if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
        requestsToRetry.append(completion)

        if !isRefreshing {
            refreshToken(completion: { [weak self] succeded, accessToken in

                guard let strongSelf = self else { return }

                strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }

                strongSelf.requestsToRetry.forEach{ $0(succeded, 0.0) }
                strongSelf.requestsToRetry.removeAll()
            })
        }
    } else {
        completion(false, 0.0)
    }
}

When strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() } strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() } strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() } is called it doesn't continue the execution so I have an infinite loop. strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }被称为它不会继续执行,因此存在无限循环。 I tried checking the result of strongSelf.lock.try() and returns false. 我尝试检查strongSelf.lock.try()的结果并返回false。

This is happening when I sign in with a wrong password so the server returns a 401. 当我使用错误的密码登录时会发生这种情况,因此服务器返回401。

This is my refreshToken code 这是我的refreshToken代码

guard !isRefreshing else { return }

// ... Get user ... //
if let user = user {

    isRefreshing = true
    signIn(user: userDTO)
        .subscribe(onNext: { [weak self] userSession in
            guard let strongSelf = self else { return }
            // ... Save accessToken ... //
            completion(true, userSession.accessToken)
            strongSelf.isRefreshing = false
        }, onError: { [weak self] error in
            guard let strongSelf = self else { return }
            // ... Log out user ... //
            completion(false, nil)
            strongSelf.isRefreshing = false
        })
        .disposed(by: bag)
} else {
        completion(false, nil)
}

As seen in the Github issue https://github.com/Alamofire/Alamofire/issues/2544 I could fix this by changing: 如Github问题https://github.com/Alamofire/Alamofire/issues/2544所示,我可以通过以下方法解决此问题:

private let lock = NSLock()

to

private let lock = NSRecursiveLock()

The difference between them is that the recursive lock can by unlocked if the same thread is trying to lock. 它们之间的区别在于,如果同一线程尝试锁定,则可以解锁递归锁定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM