初识MKNetworkKit

最近在研究MKNetworkEngine,也不能叫研究,应该算是大致浏览了一边,对部分的结构有了一点的了解 .

本片博文里,对部分比较常用的功能做了简单的介绍,至于底层的原理,本人目前能力有限,只能略知一二,网上关于这方面的资料少到又少,千篇一律( 原文地址: http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit ).

可能这些对于 大牛 来说真的是 小菜一碟 ,所以, 强烈要求路过的高手驻扎片刻,对小生指引一番 !


 MKNetworkKit的主要特点:
1.网络共享队列单例化:整个程序中只有一个主队列
2.正确显示网络状态指示
3.自动控制并发操作数:MKNetworkKit会根据网络情况自动修改并发数
4.自动缓存:MKNetworkKit能根据两次GET请求是否相同而选择是否缓存请求
5.请求冻结:当网络状态不佳时,会自动冷冻请求,等待网络情况好转时自动恢复,再次请求
6.完全支持ARC


详解:

1.网络共享队列单例化


// Network Queue is a shared singleton object.

// no matter how many instances of MKNetworkEngine is created, there is one and only one network queue

// In theory an app should contain as many network engines as the number of domains it talks to


MKNetworkEngine.m

#pragma mark Initialization

staticNSOperationQueue *_sharedNetworkQueue;

+(void) initialize 

{    

  if(!_sharedNetworkQueue)

  {    

static dispatch_once_t oncePredicate;    

dispatch_once(&oncePredicate, ^{      

_sharedNetworkQueue = [[NSOperationQueue allocinit];        

 //添加观察者,观察operationCount,     

 [_sharedNetworkQueue addObserver:[self selfforKeyPath:@"operationCount" options:0 context:NULL];     [_sharedNetworkQueue setMaxConcurrentOperationCount:6];       

   });  

  }

}



2 .正确显示网络状态显示

MKNetworkKit则由于使用了单例的共享队列,能自动显示网络状态。

在共享队列中有一个线程通过 KVO 方式会随时观察 operationCount 属性。

因此对于开发者,一般情况下根本不需要操心网络状态的显示

MKNetworkEngine类在运行时的特性initialize(见1),在方法体里边,观察 operationCount,该值改变时,调用下面方法

MKNetworkEngine.m

#pragma mark KVO for network Queue

//通过KVO监测operationCount

//实现:

+ (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{  

     if (object == _sharedNetworkQueue && [keyPath isEqualToString:@"operationCount"]){

 [[NSNotificationCenter defaultCenter]                 postNotificationName:kMKNetworkEngineOperationCountChangedobject:[NSNumber numberWithInteger:(NSInteger)[_sharedNetworkQueue operationCount]]];

#if TARGET_OS_IPHONE

[UIApplication sharedApplication].networkActivityIndicatorVisible =   ([_sharedNetworkQueue.operations count] > 0);

#endif  

}else {   [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];}

}



3.自动控制最大并发数

绝大部分移动网络不允许 2 个以上的并发连接,因此你的队列大小在3G 网络下应当设置为 2。 

MKNetworkKit 会自动为你处理好这个。

当网络出于3G/EDGE/GPRS 时,它会将并发数调整到 2。

当网络处于 Wifi 网络时,则自动调整到 6

当然MKNetworkKit会根据网络状态的改变对最大并发数进行修改.



//reachability改变时,调用,用于修改最大并发数

#pragma mark -

#pragma mark Reachability related


-(void) reachabilityChanged:(NSNotification*) notification

{

  if([self.reachabilitycurrentReachabilityStatus] == ReachableViaWiFi)

  {

    DLog(@"Server [%@] is reachable via Wifi",self.hostName);

    [_sharedNetworkQueuesetMaxConcurrentOperationCount:6];

    

    [selfcheckAndRestoreFrozenOperations];

  }

  elseif([self.reachabilitycurrentReachabilityStatus] == ReachableViaWWAN)

  {

    if(self.wifiOnlyMode) {

      

      DLog(@" Disabling engine as server [%@] is reachable only via cellular data.",self.hostName);

      [_sharedNetworkQueuesetMaxConcurrentOperationCount:0];

    } else {

      DLog(@"Server [%@] is reachable only via cellular data",self.hostName);

      [_sharedNetworkQueuesetMaxConcurrentOperationCount:2];

      [selfcheckAndRestoreFrozenOperations];

    }

  }

  elseif([self.reachabilitycurrentReachabilityStatus] == NotReachable)

  {

    DLog(@"Server [%@] is not reachable",self.hostName);

    [selffreezeOperations];

  }

  

  if(self.reachabilityChangedHandler) {

    self.reachabilityChangedHandler([self.reachabilitycurrentReachabilityStatus]);

  }

}


 

4.使用缓存


MKNetworkKit 能自动缓存你所有的 GET 请求。

当你再次发起同样的请求时,MKNetworkKit 随即就能调用 response缓存(如果可用的话)传递给 handler 进行处理。当然,它同时也向服务器发出请求。

一旦获得服务器数据,handler 被再次要求处理新获取的数据。

也就是说,你不用手动缓存。你只需要使用:

[[MKNetworkEngine sharedEngine] useCache];
当然,你可以覆盖这个方法(子类化),定制你的缓存路径和缓存占用的内存开销 

MKNetworkEngine.m文件

-(void) useCache {

  self.memoryCache = [NSMutableDictionarydictionaryWithCapacity:[selfcacheMemoryCost]];

  self.memoryCacheKeys = [NSMutableArrayarrayWithCapacity:[selfcacheMemoryCost]];

  self.cacheInvalidationParams = [NSMutableDictionarydictionary];


  NSString *cacheDirectory = [selfcacheDirectoryName];

    //cacheDirectory = /Users/apple/Library/Application Support/iPhone Simulator/6.1/Applications/550AF26D-174B-42E6-881B-B7499FAA32B7/Documents

    

  BOOL isDirectory =YES;

    //测试文件是不是目录

  BOOL folderExists = [[NSFileManagerdefaultManager] fileExistsAtPath:cacheDirectoryisDirectory:&isDirectory] && isDirectory;

  

  if (!folderExists)

  {

    NSError *error =nil;

      // 1path:所要创建文件夹的路径。

      //2createIntermediates:所要创建的目录的父目录等相关的目录可能并不存在。如果想要把相关目录一起创建了,就把这个参数设成YES,否则设成NO。设成NO的话,假如父目录不存在,函数就会失败,函数返回值就是NO

      //3attributes:这个参数就是创建目录时的一些选项设置,所有可以配置项的键可以在这里找到。一般设成nil就行了。采用默认的设置。

      //4error:函数执行错误时返回的错误对象,注意应返回的是一个地址;

    [[NSFileManagerdefaultManager] createDirectoryAtPath:cacheDirectorywithIntermediateDirectories:YESattributes:nilerror:&error];

  }

  

    //添加扩展名

  NSString *cacheInvalidationPlistFilePath = [cacheDirectorystringByAppendingPathExtension:@"plist"];

  

  BOOL fileExists = [[NSFileManagerdefaultManager] fileExistsAtPath:cacheInvalidationPlistFilePath];

  

  if (fileExists)

  {

    self.cacheInvalidationParams = [NSMutableDictionarydictionaryWithContentsOfFile:cacheInvalidationPlistFilePath];

  }

...

}



5.冻结操作


/*Freezable operations are serialized when the network goes down and restored when the connectivity is up again.
* Only POST, PUT and DELETE operations are freezable.  
*In short, any operation that changes the state of the server are freezable, creating a tweet, checking into a new location etc., Operations like fetching a list of tweets (think readonly GET operations) are not freezable.*MKNetworkKit doesn't freeze (readonly) GET operations even if they are marked as freezable

*/


MKNetworkEngine.m文件
 
-( void ) enqueueOperation:( MKNetworkOperation *) operation forceReload:( BOOL ) forceReload
{
    ...
      // 如果当前的网络状态 =NotReachable, 冻结操作

    if([self.reachability currentReachabilityStatus] == NotReachable)     

    [self freezeOperations];

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值