4

我正在查看一些 Alamofire示例Retrier 代码:

   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 {
                refreshTokens { [weak self] succeeded, accessToken, refreshToken in
                    guard let strongSelf = self else { return }

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

                    ...
                }
            }
        } else {
            completion(false, 0.0)
        }
    }

我不知道如何lock.lock()在函数的第一行使用,然后strongSelf.lock.lock()在闭包中将同一行传递给refreshTokens.

如果在执行解锁时直到should方法结束才释放第一个锁,那么第二个锁如何在第一个锁被持有时成功执行?deferstrongSelf.lock.lock()

4

1 回答 1

5

的尾随闭包refreshTokens,即第二次调用lock()/unlock()的地方,异步运行。这是因为闭包是@escaping从例程responseJSON内部调用的refreshTokens。因此,该should方法将在实际调用unlock闭包时执行其延迟。refreshTokens

话虽如此,这不是我见过的最优雅的代码,其中锁的效用不清楚,死锁的风险非常依赖于其他例程的实现细节。在这里看起来还可以,但我不怪你对它挑眉。

于 2016-10-16T00:00:44.753 回答