处理网络事务大多都在子线程中执行,可能使用NSOperationQueue,或者是GCD。有时候会有多个网络活动同时存在,因此判断是否所有网络活动已经完成,就成了一个必须面对的问题。不可以在我的线程中把自己的下载任务完成了,就停止Network Activity Indicator,需要确保所有其他线程中的任务也全部完成。这里介绍的方法就是使用单例。
下面创建一个KMTaskCenter类,来控制网络活动的单例。
接口文件:
#import <Foundation/Foundation.h>
@interface KMTaskCenter : NSObject
+ (KMTaskCenter *)sharedTaskCenter;
- (void)addNetworkingAction;
- (void)removeNetworkingAction;
@end
公共接口提供了三个方法,一个类方法,两个对象方法。类方法用来返回一个单例,对象方法用来控制添加或者结束一个网络活动。
实现文件:
#import "KMTaskCenter.h"
@interface KMTaskCenter ()
@property (nonatomic) NSUInteger networkingCount;
@end
@implementation KMTaskCenter
+ (KMTaskCenter *)sharedTaskCenter
{
static KMTaskCenter *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[KMTaskCenter alloc] init];
});
return sharedInstance;
}
- (void)addNetworkingAction
{
self.networkingCount++;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
- (void)removeNetworkingAction
{
self.networkingCount--;
if (self.networkingCount == 0) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
}
@end
在实现文件中,定义了一个networkingCount属性,用来统计有多少网络活动正在进行(不对NSUInteger初始化的话,其初始值默认为0)。 返回单例的类方法内,使用GCD来控制只创建一次对象。addNetworkingAction用来增加一个网络活动,removeNetworkingAction用来删除一个网络活动,并且在网络活动为0时,停止Network Activity Indicator的动画效果。
使用时需要先调用[KMTaskCenter sharedTaskCenter]来获得一个单例,然后进行添加或者删除网络活动计数的操作。
[[KMTaskCenter sharedTaskCenter] addNetworkingAction]; // 添加一个网络活动
[[KMTaskCenter sharedTaskCenter] removeNetworkingAction]; // 删除一个网络活动
可以在一个下载活动开始前,调用添加方法,然后在下载结束后,调用删除方法。下面再附上一段实际代码。
[[KMTaskCenter sharedTaskCenter] addNetworkingAction];
NSURL *url = [NSURL URLWithString:@"www.kweima.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:30];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data) {
NSError *parseErr = nil;
NSArray *list = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&parseErr];
if (list != nil || parseErr == nil) {
NSLog(@"Parsing data error.");
[[KMTaskCenter sharedTaskCenter] removeNetworkingAction];
} else {
NSLog(@"Parsing data error.");
[[KMTaskCenter sharedTaskCenter] removeNetworkingAction];
}
} else {
NSLog(@"Fetching data error.");
[[KMTaskCenter sharedTaskCenter] removeNetworkingAction];
}
}];