- 1.1 涉及知识点
(1)两种为NSURLConnection设置代理方式的区别
(2)如何控制代理方法在哪个线程调用
(3)开子线程发送网络请求的注意点,适用于自动发送网络请求模式
(1)两种为NSURLConnection设置代理方式的区别
//第一种设置方式: //通过该方法设置代理,会自动的发送请求 // [[NSURLConnection alloc]initWithRequest:request delegate:self]; //第二种设置方式: //设置代理,startImmediately为NO的时候,该方法不会自动发送请求 NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO]; //手动通过代码的方式来发送请求 //注意该方法内部会自动的把connect添加到当前线程的RunLoop中在默认模式下执行 [connect start];
//说明:默认情况下,代理方法会在主线程中进行调用(为了方便开发者拿到数据后处理一些刷新UI的操作不需要考虑到线程间通信) //设置代理方法的执行队列 [connect setDelegateQueue:[[NSOperationQueue alloc]init]];
(3)开子线程发送网络请求的注意点,适用于自动发送网络请求模式
//使用GCD开启一个子线程来发送网络请求 dispatch_async(dispatch_get_global_queue(0, 0), ^{ //使用非自动发送网络请求模式,发送请求OK /* //创建NSURLConnection对象,设置代理,暂不发送 NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO]; //设置代理方法的执行队列 [connect setDelegateQueue:[[NSOperationQueue alloc]init]]; //调用start发送网络请求 [connect start]; */ //使用自动发送网络请求模式,发送请求失败(需要改造代码) //WHY? /*01 网络请求发送和数据接收是否成功,和一些因素相关,比如客户端的网速、服务器端的查询速度等等。 02 而在子线程中创建的NSURLConnection对象是一个临时变量,当请求发送完成之后就被释放了,所以这个时候它的代理方法不会调用用。 03 为什么使用非自动发送网络请求模式是OK的。 因为在该模式中,调用了start来开始发送网络请求,该方法内部会自动将当前的connect作为一个Source添加到当前线程所在的Runloop中 如果当前线程是子线程(即当前线程的runloop并未创建),那么该方法内部会默认先创建当前线程的Runloop,设置在runloop的默认模式下运行。 此时runloop会对这个Connect对象进行强引用,保证了代理方法被调用的前提 */ NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self]; [connect setDelegateQueue:[[NSOperationQueue alloc]init]]; //创建当前线程的runloop,并开启runloop [[NSRunLoop currentRunLoop] run]; });