在大量的上传与下载中可靠的显示网络状态,可以使用UIApplication的networkActivityIndicatorVisible属性,方便的显示和隐藏网络的“转盘”。然而这个二进制开关没有场景信息,很难知道在什么时候隐藏它,使用类扩展,访问现有的UIApplication实例,而不用区管理额外的对象,由于活动指示器本身是由UIApplication来管理的,这么做更顺利成章。
代码:UIApplication+XYNetWorkActivity.h
#import <UIKit/UIKit.h>
@interface UIApplication (XYNetWorkActivity)
@property (nonatomic, assign, readonly) NSInteger networkActivityCount;
- (void)pushNetworkActivity;
- (void)popNetworkActivity;
- (void)resetNetworkActivity;
@end
这个扩展管理一个只读的计数器,对活动连接进行计数。通过- (void)pushNetworkActivity和- (void)popNetworkActivity两个方法把网络活动通知给app,- (void)resetNetworkActivity用于清楚当前状态,重新开始。
代码:UIApplication+XYNetWorkActivity.m
#import "UIApplication+XYNetWorkActivity.h"
static NSInteger networkActivityCount = 0;
@implementation UIApplication (XYNetWorkActivity)
- (NSInteger)networkActivityCount{
@synchronized(self){
return networkActivityCount;
}
}
- (void)pushNetworkActivity{
@synchronized(self){
networkActivityCount ++;
}
[self refreshNetworkActivityIndicator];
}
- (void)popNetworkActivity{
@synchronized(self){
if (networkActivityCount > 0) {
networkActivityCount--;
}else{
networkActivityCount = 0;
}
}
[self refreshNetworkActivityIndicator];
}
- (void)refreshNetworkActivityIndicator{
if (![NSThread isMainThread]) {
SEL sel_refresh = @selector(refreshNetworkActivityIndicator);
[self performSelectorOnMainThread:sel_refresh withObject:nil waitUntilDone:NO];
return;
}
BOOL active = (self.networkActivityCount > 0);
self.networkActivityIndicatorVisible = active;
}
- (void)resetNetworkActivity{
@synchronized(self){
networkActivityCount = 0;
}
[self refreshNetworkActivityIndicator];
}
@end
使用全区变量来存储活动计数,在对象之间共享静态变量时一定要小心,理想的办法可能时使用关联对象的方法,但是一个app中只有一个UIApplication实例,为了保持简洁,使用全局变量就行了。
在多线程环境下使用@synchronized进行线程同步。
使用方法:
在开始网络工作时:[[UIApplication sharedApplication] pushNetworkActivity];
在结束网络工作时:[[UIApplication sharedApplication] popNetworkActivity];
停止所有的网络工作:[[UIApplication sharedApplication] resetNetworkActivity];
如果担心这些方法与原有的方法冲突,可在变量和方法前加上前缀进行区别。
代码下载:链接地址