我一直惧怕写网络请求,因为感觉网络请求很难。其实不然,把它搞明白了就有种柳暗花明又一村的感觉。
进程与线程问题:
mac里面的活动监视器相当于windows里的任务管理器,可以查看系统占用和所有正在进行当中的进程。而进程是程序在计算机上的一次执行活动。当你运行一个程序,你就启动了一个进程。显然,程序是死的,进程是活的。简而言之,一个程序可以开启一个进程,一个进程可以开启一个线程,一个线程可以开启另外的线程。而同一个进程中的线程共享内存中内存和资源,进程与进程之间有通信方式传递参数。
我们都知道,一个程序启动会创建一个主线程,它是独立的。相当于程序的生命。但是在一个程序中只有一个主线程,当你执行的任务多了,则会导致主线程阻塞,进而崩溃。例如,我们在写一个程序时,往往把网络请求封装为一个类,给它重新开辟一个线程,这样主线程就负责UI界面,子线程负责请求。这样做既可以防止主线程堵塞,也可以有效提高CPU的使用率。
HTTP协议:
我们平时在浏览网页时,网址前面都会有http,它是一个协议,就像是两人做事情必须遵从的一些规则,也可可以理解为游戏规则。他的全称是超文本传输协议,是浏览器与服务器之间的通行规则。客户端发送请求给服务器,服务器给客户端响应。当我们发送请求,服务器返回的数据中,我们可以看到200,404这样的数字,这个叫做响应码。200则表示成功,404则表示请求失败。
访问网络的方式有两种:同步与异步,同步请求会堵塞主线程,无法取消请求。异步数据的请求在多线程来执行,不会阻塞,同时可以监听加载进度,取消请求。
接下来就是网络请求的一般步骤:
1.构造NSURL实例(远程服务器地址,也可以是本地地址)
2.请求NSURLRequest对象 (包装了网络请求的信息)
3.生成USURLConnection发送请求 连接服务器
4.通过返回NSURLRespnd实例和NSError实例分析结果
5.接收返回数据
我们要知道服务器是没办法向客户端发起请求,服务器压力很大,为了节省服务器端的资源,我们主动请求,请求方式有两种,post和get。post:是向服务器提交数据的一种请求方式.把数据提交给服务器,主要作用不是返回数据。像很多的登陆请求,就可以用这种方式。get :是向服务器索取数据的一种请求方式。
服务器返回的数据有两种:
1.json :这个更精简,返回的数据中{}代表字典 []代表数组
一般采用JSONKit解析数据 。IOS5之后系统自带解析库,性能好
2.xml:可扩展语言,是一种数据交换格式
(1)Dom解析:把所有数据一次性读入内存,功耗大,解析难度低
(2)Sax解析:客户端用得少,服务端用的多,S按采用逐步解析的方式,占用内存小,特点是方便、灵活、解析相对麻烦。
code:
#import "Request.h"
#import "kuaidiViewController.h"
@implementation Request
-(IBAction)requestWithGetUrl:(NSString *)urlstring{
//转码
urlstring = [urlstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//设置 url
NSURL * url = [NSURL URLWithString:urlstring];
//创建请求对象
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
request.timeoutInterval = 5.0;
//发送请求
NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];
[conn start];
NSLog(@"已经发出请求---");
}
#pragma mark = NSURLConnectDataDelegate代理方法
//当接收到服务器的响应(连通了服务器)时会调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"接受到服务器的响应");
//初始化数据
self.responseDate = [NSMutableData data];
}
//当接收到服务器的数据时会调用(可能会被调用多次,每次只传递部分数据)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"接收到服务器的数据");
[self.responseDate appendData:data];
//responseData是NSMutableData的方法
NSLog(@"%d-----%@-----",self.responseDate.length,[NSThread currentThread]); //[NSThread currentThread]获取当前线程
}
//当服务器的数据加载完毕时就会调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"服务器的数据加载完毕");
// 发送异步请求有两种方式:1)使用block回调 2)代理
[self.delegate requestFinished:_responseDate]; //这里采用的是代理
}
//请求错误(失败)的时候调用(请求超时\断网\没有网\,一般指客户端错误)
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"网络繁忙");
}
@end