NSLock.lock() выполняется, пока блокировка уже удерживается?
Я рассматриваю пример кода Retrier 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)
}
}
Я не понимаю, как вы можете иметь lock.lock()
в первой строке функции, а затем также имеют ту же строку strongSelf.lock.lock()
в закрытии передается refreshTokens
,
Если первая блокировка не снята до конца should
метод, когда defer
разблокировка выполняется как вторая strongSelf.lock.lock()
успешно выполнить, пока удерживается первая блокировка?
1 ответ
Завершающее закрытие refreshTokens
где этот второй вызов lock()
/unlock()
называется, работает асинхронно. Это потому, что закрытие @escaping
и вызывается изнутри responseJSON
внутри refreshTokens
рутина. Итак should
метод выполнил отложенный unlock
к моменту закрытия refreshTokens
на самом деле называется.
Сказав это, это не самый элегантный код, который я когда-либо видел, где полезность блокировки неясна, а риск взаимоблокировки так зависит от деталей реализации других подпрограмм. Похоже, здесь все в порядке, но я не виню вас за то, что вы подняли бровь.