咱們先從 NSURLConnection 作一個get請求:php
- (void)reqConnection { NSLog(@"異步請求測試開始..."); NSURL *url = [NSURL URLWithString:@"http://ip.taobao.com/service/getIpInfo.php?ip=myip"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSLog(@"立刻進行異步鏈接請求url的數據"); [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {//[NSOperationQueue currentQueue]決定block在哪一個隊列執行 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; NSLog(@"data:%@",dict); if (data.length > 0 && connectionError == nil) { NSLog(@"%lu字節的數據被返回",(unsigned long)data.length); }else if (connectionError == nil && data.length == 0) { NSLog(@"沒有數據返回。。"); }else if (connectionError != nil) { NSLog(@"返回錯誤"); } }]; NSLog(@"異步請求測試完成。。"); }
拋開原理不說,單從請求方式來講和 AF裏的 :html
//startImmediately 是否當即開始 self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease]; assert(self.connection != nil); for (NSString * mode in self.actualRunLoopModes) { [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; } [self.connection start];
來分析思考下 有什麼區別:最上面的用的是block,下面這個用的是代理:網絡
@implementation ViewController - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@"接收到請求:%@",response); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; NSLog(@"didReceiveData dict:%@",dict); } - (void)viewDidLoad { [super viewDidLoad]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://ip.taobao.com/service/getIpInfo.php?ip=myip"]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; [connection start];
接下來看看 這裏所謂的 runloop都在幹嗎?多線程
for (NSString * mode in self.actualRunLoopModes) { [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; }
**能夠將NSTimer手動加入NSRunLoop,Cocoa庫也爲其它一些類提供了能夠手動加入NSRunLoop的方法,這些類有NSPort、NSStream、NSURLConnection、NSNetServices,方法都是[scheduleInRunLoop:forMode:]形式。我暫時只介紹下最經常使用的NSURLConnection類,看看如何把NSURLConnection的網絡下載加入到其它線程的run loop去運行。異步
若是NSURLConnection是在主線程中啓動的,實際上它就在主線程中運行 -- 並不是啓動的另外的線程,但又具有異步運行的特性,這個確實是run loop的巧妙所在。若是對run loop有了初步的瞭解和概念後,實際上就能明白NSURLConnection的運行,實際也是須要當前線程具有run loop。oop
如何讓NSURLConnection在子線程中運行,參考資料:https://blog.csdn.net/lengshengren/article/details/12905697測試
多線程:http://www.javashuo.com/article/p-xtgdggjj-hw.htmlurl
爲何別人都這麼經常使用多線程,而本身用的卻不多,因此好好留心 ,多思考 多用。.net