通過NSURLConnection進(jìn)行異步下載
NSURLConnection提供了兩種方式來實現(xiàn)連接,一種是同步的另一種是異步的,異步的連接將會創(chuàng)建一個新的線程,這個線程將會來負(fù)責(zé)下載的動作礼预。而對于同步連接,在下載連接和處理通訊時,則會阻塞當(dāng)前調(diào)用線程估盘。
許多開發(fā)者都會認(rèn)為同步的連接將會堵塞主線程,其實這種觀點是錯誤的呀枢。一個同步的連接是會阻塞調(diào)用它的線程控漠。如果你在主線程中創(chuàng)建一個同步連接,沒錯,主線程會阻塞侍筛。但是如果你并不是從主線程開啟的一個同步的連接,它將會類似異步的連接一樣。因此這種情況并不會堵塞你的主線程。事實上,同步和異步的主要區(qū)別就是運(yùn)行runtime為會異步連接創(chuàng)建一個線程,而同步連接則不會。
[objc]view plaincopyprint?
//asynchronousRequest?connection
-(void)fetchAppleHtml{
NSString*urlString?=@"http://www.apple.com";
NSURL*url?=?[NSURLURLWithString:urlString];
//????NSURLRequest?*urlRequest?=?[NSURLRequest?requestWithURL:url];
NSURLRequest*urlRequest?=?[NSURLRequestrequestWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheDatatimeoutInterval:30.0f];//maximal?timeout?is?30s
NSOperationQueue*queue?=?[[NSOperationQueuealloc]init];
[NSURLConnectionsendAsynchronousRequest:urlRequestqueue:queuecompletionHandler:^(NSURLResponse*response,NSData*data,NSError*connectionError)?{
if([datalength]?>0&&?connectionError?==nil)?{
NSString*documentsDir?=?[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,?NSUserDomainMask,YES)objectAtIndex:0];
NSString*filePath?=?[documentsDirstringByAppendingPathComponent:@"apple.html"];
[datawriteToFile:filePathatomically:YES];
NSLog(@"Successfully?saved?the?file?to?%@",filePath);
NSString*html?=?[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
NSLog(@"HTML?=?%@",html);
}elseif([datalength]?==0&&?connectionError?==nil){
NSLog(@"Nothing?was?downloaded.");
}elseif(connectionError?!=nil){
NSLog(@"Error?happened?=?%@",connectionError);
}
}];
}
通過NSURLConnection進(jìn)行同步下載
使用NSURLConnection的sendSynchronousRequest:returningResponse:error:類方法,我們可以進(jìn)行同步請求姻几。在創(chuàng)建一個同步的網(wǎng)絡(luò)連接的時候我們需要明白一點,并不是是我們的這個同步連接一定會堵塞我們的主線程,如果這個同步的連接是創(chuàng)建在主線程上的,那么這種情況下是會堵塞我們的主線程的,其他的情況下是不一定會堵塞我們的主線程的。如果你在GCD的全局并發(fā)隊列上初始化了一個同步的連接,你其實并不會堵塞我們的主線程的势告。
我們來初始化第一個同步連接,并看看會發(fā)生什么蛇捌。在實例中,我們將嘗試獲取Yahoo!美國站點主頁內(nèi)容:
[objc]view plaincopyprint?
//synchronousRequest?connection
-(void)fetchYahooData{
NSLog(@"We?are?here...");
NSString*urlString?=@"http://www.yahoo.com";
NSURL*url?=?[NSURLURLWithString:urlString];
NSURLRequest*urlRequest?=?[NSURLRequestrequestWithURL:url];
NSURLResponse*response?=nil;
NSError*error?=nil;
NSLog(@"Firing?synchronous?url?connection...");
NSData*data?=?[NSURLConnectionsendSynchronousRequest:urlRequestreturningResponse:&responseerror:&error];
if([datalength]?>0&&?error?==nil)?{
NSLog(@"%lu?bytes?of?data?was?returned.",(unsignedlong)[datalength]);
}elseif([datalength]?==0&&?error?==nil){
NSLog(@"No?data?was?return.");
}elseif(error?!=nil){
NSLog(@"Error?happened?=?%@",error);
}
NSLog(@"We?are?done.");
}
/*
|
|?as?we?know,?it?will?chock?main?thread?when?we?call?sendSynchronousRequest?on?main?thread,,,,change?below
|
v
*/
//call?sendSynchronousRequest?on?GCD?pool
-(void)fetchYahooData2_GCD{
NSLog(@"We?are?here...");
NSString*urlString?=@"http://www.yahoo.com";
NSLog(@"Firing?synchronous?url?connection...");
dispatch_queue_t?dispatchQueue?=?dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(dispatchQueue,?^{
NSURL*url?=?[NSURLURLWithString:urlString];
NSURLRequest*urlRequest?=?[NSURLRequestrequestWithURL:url];
NSURLResponse*response?=nil;
NSError*error?=nil;
NSData*data?=?[NSURLConnectionsendSynchronousRequest:urlRequestreturningResponse:&responseerror:&error];
if([datalength]?>0&&?error?==nil)?{
NSLog(@"%lu?bytes?of?data?was?returned.",(unsignedlong)[datalength]);
}elseif([datalength]?==0&&?error?==nil){
NSLog(@"No?data?was?returned.");
}elseif(error?!=nil){
NSLog(@"Error?happened?=?%@",error);
}
});
NSLog(@"We?are?done.");
}
查看運(yùn)行輸出結(jié)果,分別為:
synchronous download on main thread without GCD
synchronous download on main thread with GCD
可以看到在主線程上調(diào)用同步下載會阻塞當(dāng)前線程咱台,而使用GCD則不會络拌。
通過NSURLConnection發(fā)送一個HTTP GET請求
[objc]view plaincopyprint?
//send?a?GET?request?to?server?with?some?params
-(void)httpGetWithParams{
NSString*urlString?=@"http://chaoyuan.sinaapp.com";
urlString?=?[urlStringstringByAppendingString:@"?p=1059"];
NSURL*url?=?[NSURLURLWithString:urlString];
NSMutableURLRequest*urlRequest?=?[NSMutableURLRequestrequestWithURL:url];
[urlRequestsetTimeoutInterval:30.0f];
[urlRequestsetHTTPMethod:@"GET"];
NSOperationQueue*queue?=?[[NSOperationQueuealloc]init];
[NSURLConnectionsendAsynchronousRequest:urlRequestqueue:queuecompletionHandler:^(NSURLResponse*response,NSData*data,NSError*connectionError)?{
if([datalength]?>0&&?connectionError?==nil)?{
NSString*html?=?[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
NSLog(@"HTML?=?%@",html);
}elseif([datalength]?==0&&?connectionError?==nil){
NSLog(@"nothing?was?download.");
}elseif(connectionError?!=nil){
NSLog(@"Error?happened?=?%@",connectionError);
}
}];
}
通過NSURLConnection發(fā)送一個HTTP POST請求
[objc]view plaincopyprint?
//send?a?POST?request?to?a?server?with?some?params
-(void)httpPostWithParams{
NSString*urlAsString?=@"http://chaoyuan.sinaapp.com";
urlAsString?=?[urlAsStringstringByAppendingString:@"?param1=First"];
urlAsString?=?[urlAsStringstringByAppendingString:@"?m2=Second"];
NSURL*url?=?[NSURLURLWithString:urlAsString];
NSMutableURLRequest*urlRequest?=?[NSMutableURLRequestrequestWithURL:url];?[urlRequestsetTimeoutInterval:30.0f];
[urlRequestsetHTTPMethod:@"POST"];
NSString*body?=@"bodyParam1=BodyValue1&bodyParam2=BodyValue2";?[urlRequestsetHTTPBody:[bodydataUsingEncoding:NSUTF8StringEncoding]];NSOperationQueue*queue?=?[[NSOperationQueuealloc]init];
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:queuecompletionHandler:^(NSURLResponse*response,NSData*data,
NSError*error)?{
if([datalength]?>0&&
error?==nil){
NSString*html?=?[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];?NSLog(@"HTML?=?%@",?html);
}
elseif([datalength]?==0&&
error?==nil){
NSLog(@"Nothing?was?downloaded.");
}
elseif(error?!=nil){
NSLog(@"Error?happened?=?%@",?error);
}
}];
}