我在繼承NSURLProtocol
攔截HTTP請求。自定義NSURLProtocol導致__psynch_mutexwait
這裏是自定義NSURLProtocol
類。
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if (NSOrderedSame != [request.URL.scheme caseInsensitiveCompare:@"http"] &&
NSOrderedSame != [request.URL.scheme caseInsensitiveCompare:@"https"]) {
return NO;
}
if ([NSURLProtocol propertyForKey:kURLProtocolRequestHandledKey inRequest:request]) {
return NO;
}
return YES;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
NSMutableURLRequest *mutableReqeust = [request mutableCopy];
[NSURLProtocol setProperty:@YES forKey:kURLProtocolRequestHandledKey inRequest:mutableReqeust];
return [mutableReqeust copy];
}
- (void)startLoading {
self.startDate = [NSDate date];
self.data = [NSMutableData data];
self.error = nil;
self.connection = [[NSURLConnection alloc] initWithRequest:[[self class] canonicalRequestForRequest:self.request] delegate:self startImmediately:YES];
}
- (void)stopLoading {
[self.connection cancel];
}
#pragma mark - NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[self client] URLProtocol:self didFailWithError:error];
self.error = error;
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection {
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[self client] URLProtocol:self didReceiveAuthenticationChallenge:challenge];
}
- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[self client] URLProtocol:self didCancelAuthenticationChallenge:challenge];
}
#pragma mark - NSURLConnectionDataDelegate
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
if (response != nil){
_response = response;
NSMutableURLRequest *redirect = [request mutableCopy];
redirect.URL = request.URL;
[NSURLProtocol setProperty:@NO forKey:kURLProtocolRequestHandledKey inRequest:redirect];
[[self client] URLProtocol:self wasRedirectedToRequest:redirect redirectResponse:response];
return redirect;
}
return request;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
_response = response;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[[self client] URLProtocol:self didLoadData:data];
[self.data appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return cachedResponse;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[[self client] URLProtocolDidFinishLoading:self];
}
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
}
我添加UIWebView
作爲一個子視圖,然後加載URL http://ln.clientaccess.10086.cn/shop/optical/Appointment?channel=007&PHONE_NUM=18240235054&AREA_CODE=240&key=4A35774433BA79EB950EDE4B5C4D7121
,控制器被駁回後,應用程序被凍結,即使我打電話- stopLoading
上web視圖它駁回了。
這裏是線程堆棧:
感謝您的回覆。重定向實施是可以的。 我讀過一些'NSURLProtocol'教程也調用'startImmediately:YES',我認爲這不是問題。 – Weizhi
我在NSURLProtocol類上花了更多的時間,比我關心的承認...我相信如果你不返回nil與重定向,它不會傳回到原始的NSURLConnection委託。我已經很仔細地測試了一堆協議。我沒有看到很多教程正確。另一方面,如果你實際上沒有獲得重定向,那不會是一個問題。如果你更多地擴展回溯,這可能會有所幫助 - 你會遇到死鎖,但是不清楚主線程是否自己或其他線程死鎖。 –
WebView在'viewDidLoad'中啓動請求: ' - (void)viewDidLoad {super viewDidLoad]; NSString * URLString = @「http://ln.clientaccess.10086.cn/shop/optical/Appointment?channel=007&PHONE_NUM=18240235054&AREA_CODE=240&key=4A35774433BA79EB950EDE4B5C4D7121」; NSURL * URL = [NSURL URLWithString:URLString]; [[self webView] loadRequest:[NSURLRequest requestWithURL:URL]]; }' 該URL有66個請求,沒有重定向URL,我認爲重定向不是問題。 – Weizhi