NSLock.lock()在已持有锁的情况下执行?

Mar*_*eon 4 closures nslock swift alamofire

我正在审查一些Alamofire 示例检索器代码:

   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)
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不了解如何lock.lock()在函数的第一行中包含内容,然后strongSelf.lock.lock()在传递给的闭包中包含相同的内容refreshTokens

如果在执行解锁should时直到方法结束时才defer释放strongSelf.lock.lock()第一个锁,那么在保持第一个锁的同时如何成功执行第二个锁呢?

Rob*_*Rob 5

的尾随闭包(refreshTokens第二个对lock()/ unlock()的调用在其中)的异步运行。这是因为封闭的@escaping,并从内部被称为responseJSON内部refreshTokens程序。因此,该should方法将在实际调用unlock闭包时执行延迟的操作refreshTokens

话虽如此,这并不是我所见过的最优雅的代码,其中锁的用途尚不清楚,并且死锁的风险非常取决于其他例程的实现细节。在这里看起来还可以,但我不怪你对此大惊小怪。