锁定已经执行时执行了NSLock.lock()吗?

时间:2016-10-15 22:33:50

标签: swift closures alamofire nslock

我正在审核一些Alamofire sample 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解锁时defer方法结束之前没有释放第一个锁,那么在第一个锁被执行时第二个strongSelf.lock.lock()如何成功执行?

1 个答案:

答案 0 :(得分:4)

调用<div id="map-canvas"></div> <script src="https://maps.googleapis.com/maps/api/js"></script> <script> var map; function initialize() { var mapOptions = { center: new google.maps.LatLng(40.7127837, -74.0059413), zoom: 11, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); var myLatlng = new google.maps.LatLng(40.7127837, -74.0059413); var marker = new google.maps.Marker({ position: myLatlng, map: map, title: "'. $xmladd .'" }); var myLatlng2 = new google.maps.LatLng(40.735657, -74.1723667); var marker2 = new google.maps.Marker({ position: myLatlng2, map: map, title: "'. $xmladd2 .'" }); } google.maps.event.addDomListener(window, 'load', initialize); google.maps.event.addDomListener(window, "resize", function() { var center = map.getCenter(); google.maps.event.trigger(map, "resize"); map.setCenter(center); }); </script> / refreshTokens的第二次调用的lock()的尾随闭包是异步运行的。这是因为闭包是unlock(),并且是在@escaping例程内的responseJSON内调用的。因此,refreshTokens方法在实际调用should的关闭时将执行其延迟unlock

话虽如此,这不是我见过的最优雅的代码,其中锁的效用不明确,死锁的风险依赖于其他例程的实现细节。它看起来好像在这里,但我不会责怪你挑眉。