AFNetworking阅读(二)

来源:互联网 发布:dns的默认端口 编辑:程序博客网 时间:2024/06/14 04:40
在上文中,提到了 AFNetworkActivityIndicatorManager,用于查看现在使用应用网络。今天了解如何实现小菊花。

  • 我的问题
  1. 怎么样在status bar上显示小菊花;
  2. 如何判断小菊花的显示和隐藏,判断网络请求的开始和结束?

  • 解决问题
  1. 如何显示小菊花?
         
系统的自带的方法:
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible];

AFN的AFNetworkActivityIndicatorManager就是对小菊花的管理:
/**
 * 
属性设置是否可用,不可用的时候设置状态AFNetworkActivityManagerStateNotActive,即不活跃状态
 */

- (
void)setEnabled:(BOOL)enabled {
   
_enabled= enabled;
   
if (enabled == NO) {
        [
selfsetCurrentState:AFNetworkActivityManagerStateNotActive];
    }
}
在AppDelegate中已经设置小菊花可用,故我们需要考虑的是小菊花的显示和隐藏。

2.如何判断小菊花的显示和隐藏,判断网络请求的开始和结束?
 按照我们使用小菊花的情况,小菊花的显示和隐藏式根据请求完成状态的不同而不同的。故这里要涉及到状态的处理和转移(处理就是指遇到这个状态我应该做什么,转移表示的是如何进行状态转移的)


AFNetworkActivityIndicatorManager文件中定义了四种状态分别为:
//枚举状态
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
    AFNetworkActivityManagerStateNotActive,
// 不活跃
    AFNetworkActivityManagerStateDelayingStart,
// 开始
    AFNetworkActivityManagerStateActive,
// 活跃
    AFNetworkActivityManagerStateDelayingEnd
// 停止
};

状态迁移图:



// 更新状态的方法
- (
void)updateCurrentStateForNetworkActivityChange {
   
// 可以使用
   
if (self.enabled) {
       
// switch现在的状态
       
switch(self.currentState) {
               
//如果不活跃状态
           
caseAFNetworkActivityManagerStateNotActive:
               
if(self.isNetworkActivityOccurring) {//网络请求发生
                   
//设置开始时延状态
                    [
selfsetCurrentState:AFNetworkActivityManagerStateDelayingStart];
                }
               
break;
           
caseAFNetworkActivityManagerStateDelayingStart:
               
//No op. Let the delay timer finish out.
               
break;
               
//活跃状态
           
caseAFNetworkActivityManagerStateActive:
             
//网络请求发生不发生
               
if(!self.isNetworkActivityOccurring) {
                   
//设置为时延结束状态
                    [
selfsetCurrentState:AFNetworkActivityManagerStateDelayingEnd];
                }
               
break;
               
//结束时延状态
           
caseAFNetworkActivityManagerStateDelayingEnd:
               
//网络请求发生
               
if(self.isNetworkActivityOccurring) {
                   
//设置为活跃状态
                    [
selfsetCurrentState:AFNetworkActivityManagerStateActive];
                }
               
break;
        }
    }
}


isNetworkActivityOccurring属性是根据activityCount来决定的发现activityCount的增减是通过incrementActivityCountdecrementActivityCount两个函数进行的。

// 状态处理
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
   
// 线程锁,防止多个线程同时修改状态
   
@synchronized(self) {
       
if (_currentState!= currentState) {
           
// 将要改变当前状态
            [
selfwillChangeValueForKey:@"currentState"];
           
// 设置当前状态
           
_currentState= currentState;
           
// 在各个转状态的处理
           
switch(currentState) {
                   
//不活跃状态
               
caseAFNetworkActivityManagerStateNotActive:
                   
//取消处理和完成时延的定时器
                    [
selfcancelActivationDelayTimer];
                    [
selfcancelCompletionDelayTimer];
                   
//不显示
                    [
selfsetNetworkActivityIndicatorVisible:NO];
                   
break;
                   
//开始时延
               
caseAFNetworkActivityManagerStateDelayingStart:
                   
//开启处理时延的定时器
                    [
selfstartActivationDelayTimer];
                   
break;
                   
//活跃状态
               
caseAFNetworkActivityManagerStateActive:
                   
//取消完成时延定时器
                    [
selfcancelCompletionDelayTimer];
                   
//菊花可见
                    [
selfsetNetworkActivityIndicatorVisible:YES];
                   
break;
                   
//完成时延
               
caseAFNetworkActivityManagerStateDelayingEnd:
                   
//开启完成时延的定时器
                    [
selfstartCompletionDelayTimer];
                   
break;
            }
        }
        [
selfdidChangeValueForKey:@"currentState"];
    }
}



知识点:手动通知

KVO中有两种通知Observer的方式,自动通知和手动通知。自动通知顾名思义就是只要值变化了,就自动通知观察者。

但是有时候我们有些地方的值变化了,并不想通知观察者亦或不想立即通知观察者,或者
此处虽然值还没变,但是我也想通知观察者,那么就可以使用手动通知,在你想发送给观察者消息的地方,加上willChangeValueForKey和didChangeValueForKey。

说白了只要加上这两句话,就会通知观察者,不管是不是值变化了(亲测值没变化也有效)。不过,在此之前最好是把自动通知关掉,可以利用automaticallyNotifiesObserversForKey:来返回NO,达到关闭自动通知的功能(当然,开着也行,那么自动通知和手动通知会揉在一起,执行起来很乱)。
0 0