网络服务几乎是每一款成功APP的必备条件,打开你手机你会发现里面不用联网的应用数量十只手指可以数出来,就算是一些以独特技术切入市场的APP如美颜相机,都至少加入了分享功能。下面我先做下简单的回顾兼扫盲。

  苹果定义了NSConnection 这个类来专门处理网络请求,并且这个类有两种用法来满足开发者需求。

用法一,同步请求  

 //NSURLConnection.h
 @interface NSURLConnection (NSURLConnectionSynchronousLoading)
  + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
 @end
//**.m
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:response error:error];

这种用法比较少人使用,因为他无法捕捉传输过程的内容,并且需要在子线程中使用,不然将会卡住主线程的UI绘制,直到sendSynchronousRequest返回data,但胜在简单易用,一目了然。

用法二,异步请求  

//NSURLConnection.h

 @interface NSURLConnection : NSObject

 - (instancetype)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;
- (void)start;
@end
//**.m
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[connection start];

相比第一种用法,第二种顿时让人云里雾里,特别nsrunloop更让人疑问,另外,上面的代码仅仅是开始请求部分,数据接收部分的代码还没贴出来。

细心的人注意到,在.m文件中,NSConnection初始化时传入了一个delegate,是的,数据便是通过NSURLConnectionDataDelegate的回调来处理的。

//NSURLConnection.h
@protocol NSURLConnectionDataDelegate <NSURLConnectionDelegate>
@optional
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
@end

为了不让其他函数扰乱了大家的实现,这里我只贴出跟本文有关的函数,从字面上大家都能知道这他们的作用了,didReceiveData会携带着请求下来的数据data多次回调,didFinishLoading是在请求结束后调用,另外还有一个didFailWithError在请求失败是调用,只不错他是老爸NSURLConnectionDelegate的内容。

下面我们回到第二种用法的.m文件,这里面涉及到runloop的执行机制,我在这里只解释为什么要这样设置。

Runloop有五种运行模式,这里我只说三种:

1,NSDefaultRunLoopMode: 默认的运行模式,除了NSConnection对象的事件;

2,UITrackingRunLoopMode: 用于跟踪触摸事件触发的模式(例如UIScrollView上下滚动),主线程当触摸事件触发时会设置为这个模式;

3,NSRunLoopCommonModes: 是一组常用的模式集合,简单来将就是模式集合,既然是集合,当然包括上面的两种模式。

默认情况下NSURLConnection,NSTimer都是运行1模式下,那么问题来了,假如这个时候用户刷一下屏幕,此时切换为模式2,而这时候刚好有数据请求下来,那么就悲剧了,didReceiveData不会回调。(如果NSTimer涉及精密的数据计算,这里也要注意下)解决办法就是替换成NSRunLoopCommonModes。

著名的SDWebImage在网络异步请求图片时也是使用第二种方法,个人觉得这种方法相当高效,在不创建新线程的情况下,依靠runloop来监听网络请求数据,如果同学们还是有点凌乱,不妨试下将NSURLConnection替换成NSTimer这样,其实原理都差不多。

另外这里有一点NSConnection在初始化的时候要注意startImmediately:不能设置为YES,如果你设置为YES,后在设置runloopmode是无效的。

现在理解了网络请求最具高效的方案(个人认为。。。),有没有感觉这些代理什么挺繁琐的,而一个APP不可能只有一个网络请求接口,这时候我们就需要一个管理者的角色,我们暂时将它命名为HttpManager。一个manager统领着一群connection,这时候你发现问题又来了,connection从外表上看长得都一样,没有可以标记的东西,于是,我们给他造个子类MyURLConnection 并且加多一个tag字段,来互相辨认。如图:

有了tag后,tag用什么来装填好呢,对tag唯一的要求就是不重复,这里我就直接使用url来做tag,因为除非奇葩需求,否侧url重复请求确实没有必要。

在didReceivaData中,_dataTagMap跟据tag,追加数据;

在sendHttpRequestWithUrl中,先检查_connectionTagMap中是否已经有以该url为key的对象了,有就说明已经这条请求,这条请求可以丢弃了。没有就new一个MyURLConnection 并将url作为tag,最后以url为key ,myconnection为value填入_connectionTagMap中;

在didFinishLoading中,根据connect的tag值,将对应的connection从_dataTagMap中提出来并发给对应的Model层处理,并从_dataTagMap和_connectionTagMap移除相应项;

好像听起来很简单的样子,实际上,也很简单。。。这里的发给Model层可能有些同学有迷糊了,什么叫发?大家注意到前面_connectionTagMap如果发现有重复直接丢弃即return,所以这要求HttpManager和与之交互的类必须低耦合,所以这里的发意思是指使用通知

 [[NSNotificationCenter defaultCenter] postNotificationName:KHTTPMgrNotificationSendRequestCompleted object:self userInfo:info];

info其实就一个NSDictionary,里面你想装什么就装什么,用过都知道。

今天先到这里吧,本来想写两种请求框架对比,结果只写了一种也只写了一半,只好下周末再补上对应的网络业务Model层以及另外一种请求框架了。

iOS WebServiceFramework网络服务框架浅解的更多相关文章

  1. iOS 开发之照片框架详解(2)

    一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLib ...

  2. iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

    本文链接:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 这里接着前文<iOS ...

  3. iOS 开发之照片框架详解之二 —— PhotoKit 详解(上)

    转载自:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-two.html 一. 概况 本文接着 iOS 开 ...

  4. iOS 开发之照片框架详解

    转载自:http://kayosite.com/ios-development-and-detail-of-photo-framework.html 一. 概要 在 iOS 设备中,照片和视频是相当重 ...

  5. greenev —— Python 异步网络服务框架

    greenev是一个基于greenlet协程,事件驱动,非阻塞socket模型的Python网络服务框架,它使得可以编写同步的代码,却得到异步执行的优点. 本项目受到gevent, openresty ...

  6. [apue] 一个工业级、跨平台的 tcp 网络服务框架:gevent

    作为公司的公共产品,经常有这样的需求:就是新建一个本地服务,产品线作为客户端通过 tcp 接入本地服务,来获取想要的业务能力. 与印象中动辄处理成千上万连接的 tcp 网络服务不同,这个本地服务是跑在 ...

  7. 一个工业级、跨平台、轻量级的 tcp 网络服务框架:gevent

    前言 作为公司的公共产品,经常有这样的需求:就是新建一个本地服务,产品线作为客户端通过 tcp 接入本地服务,来获取想要的业务能力.与印象中动辄处理成千上万连接的 tcp 网络服务不同,这个本地服务是 ...

  8. iOS 开发之照片框架详解(1)

    http://kayosite.com/ios-development-and-detail-of-photo-framework.html/comment-page-1 一. 概要 在 iOS 设备 ...

  9. iOS 开发之照片框架详解(3)

    http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 三. 常用方法的封装 虽然 Phot ...

随机推荐

  1. Linux 下查看文件字符编码和转换编码

    Linux 下查看文件字符编码和转换编码 如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linu ...

  2. Awesome-awesome-awesome

    Awesome-awesome-awesome A curated list of curated lists of awesome lists. awesome-awesomes @sindreso ...

  3. ganglia对于tomcat进程的res内存监控扩展

    ganglia是采用yum的安装,因此安装相关内容路径可能不同,但是不影响插件的扩展编写: 本次介绍的扩展是采用python脚本进行扩展,因此监控节点上需要安装python的相关插件: sudo yu ...

  4. CodeForces 474.D Flowers

    题意: 有n朵花排成一排,小明要么吃掉连续的k朵白花,或者可以吃单个的红花. 给出一个n的区间[a, b],输出总吃花的方法数模 109+7 的值. 分析: 设d(i)表示吃i朵花的方案数. 则有如下 ...

  5. NoSQL开篇——为什么要使用NoSQL

    NoSQL在2010年风生水起,大大小小的Web站点在追求高性能高可靠性方面,不由自主都选择了NoSQL技术作为优先考虑的方面.今年伊始,InfoQ中文站有幸邀请到凤凰网的孙立先生,为大家分享他之于N ...

  6. 【大数处理、正则表达式】NYOJ-513

    [正则] 正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”). 模式描述在搜索文本时要匹配的一个或多个字符串. 常用字符: //正则表达式 //$ 匹配 ...

  7. Android中FragmentPagerAdapter对Fragment的缓存(一)

    ViewPager + FragmentPagerAdapter,时我们经常使用的一对搭档,其实际应用的代码也非常简单,但是也有一些容易被忽略的地方,这次我们就来讨论下FragmentPagerAda ...

  8. js中json与数组字符串的相互转化

    <SCRIPT LANGUAGE="JavaScript"> var t="{'firstName': 'cyra', 'lastName': 'richar ...

  9. 通过js检测到iframe,使父窗口重定向到index -----------???----------------------

    通过js检测到iframe,使父窗口重定向到index -----------???---------------------- 如果本身已将在iframe中,那么重定向的页面应该直接添加到父级ifr ...

  10. 网站sqlserver提权操作

    在入侵过程中,得到SQLserver的权限,想进一步得到system权限的方法总结 *************************** 利用xp_cmdshell **************** ...