网络服务几乎是每一款成功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. 【HDOJ】4080 Stammering Aliens

    1. 题目描述给定一个长为$n \in [1, 4000]$的字符串,求其中长度最长的子串,并且该子串在原串中出现至少$m$次,并求最右起始位置. 2. 基本思路两种方法:二分+后缀数组,或者二分+哈 ...

  2. CY7C68013A的一点总结

    一. 值得参考的资料:FX2 TechRefManual.USB应用开发宝典. LabVIEW-USB通信简单教程(用于参考生成labview驱动程序).USB设备请求和描述符整理(仅用于理解描述符的 ...

  3. Effective C++学习笔记 条款06:如不想使用编译器自动生成的函数,就该明确拒绝

    一.为驳回编译器自动提供的机能,可将相应成员函数声明为private并且不予实现.(如果你仅仅是自己不实现的话,编译器会帮你实现) 如: class A { public: A(const strin ...

  4. UVa 1640 (计数) The Counting Problem

    题意: 统计[a, b]或[b, a]中0~9这些数字各出现多少次. 分析: 这道题可以和UVa 11361比较来看. 同样是利用这样一个“模板”,进行区间的分块,加速运算. 因为这里没有前导0,所以 ...

  5. Share SDK 第三方登录

    import java.util.HashMap; import org.apache.http.Header; import android.app.Activity; import android ...

  6. 【C#学习笔记】播放wma/mp3文件

    using System; using System.Runtime.InteropServices; namespace ConsoleApplication { class Program { [ ...

  7. java 错误:找不到或无法加载主类的解决办法

    此类错误的常见解决办法: 1.是因为.java文件不在项目的src路径内,也就是说源代码未被eclipse编译,字节码不存在无法运行了在项目名上右键 -> Builder Path -> ...

  8. Dataguard三种保护模式

    Oracle Data Guard 提供三种高水平的数据保护模式来平衡成本.可用性.性能和事务保护.可以使用任意可用管理界面来轻松地设置这些模式.要确定适当的数据保护模式,企业需要根据用户对系统响应时 ...

  9. Android自定义的webView——可实现的网页文本的复制

    package com.example.customlinearlayout.view; import android.app.ProgressDialog; import android.conte ...

  10. .NET之美——C#中的委托和事件(续)

    C#中的委托和事件(续) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为 ...