源碼閱讀:AFNetworking(十一)——UIActivityIndicatorView+AFNetworking

該文章閱讀的AFNetworking的版本爲3.2.0。bash

這是一個UIActivityIndicatorView類的分類,這個類提供了一個根據task的加載狀態自動控制加載菊花顯示和隱藏的方法。異步

1.接口文件

1.1.方法

接口文件只向外部暴露了一個方法:async

/**
 爲一個指定的task綁定一個加載菊花控件
 */
- (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task;
複製代碼

2.實現文件

2.1.AFActivityIndicatorViewNotificationObserver私有類

2.1.1.接口

2.1.1.1.屬性

/**
 加載菊花控件
 */
@property (readonly, nonatomic, weak) UIActivityIndicatorView *activityIndicatorView;
複製代碼

2.1.1.2.方法

/**
 以指定的加載菊花控件初始化
 */
- (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView;

/**
 設置要綁定的task
 */
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;
複製代碼

2.1.2.實現

  • 接口方法
- (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView
{
    self = [super init];
    if (self) {
        // 保存傳入的加載菊花控件
        _activityIndicatorView = activityIndicatorView;
    }
    return self;
}

- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
    // 建立通知中心對象
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    
    // 先移除掉以前添加通知
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
    
    // 若是傳入的task不爲nil
    if (task) {
        // 若是task的狀態不是已經執行完成
        if (task.state != NSURLSessionTaskStateCompleted) {
            // 若是task的狀態是運行中就顯示加載菊花控件,不然就隱藏
            UIActivityIndicatorView *activityIndicatorView = self.activityIndicatorView;
            if (task.state == NSURLSessionTaskStateRunning) {
                [activityIndicatorView startAnimating];
            } else {
                [activityIndicatorView stopAnimating];
            }

            // 註冊通知監聽task的開始、完成和暫停
            [notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingTaskDidResumeNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidCompleteNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidSuspendNotification object:task];
        }
    }
}
複製代碼
  • 通知回調方法
- (void)af_startAnimating {
    // 若是接收到了task啓動的通知,就在主隊列異步回調中顯示加載菊花控件
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.activityIndicatorView startAnimating];
    });
}

- (void)af_stopAnimating {
    // 若是接收到了task完成或暫停的通知,就在主隊列異步回調中隱藏加載菊花控件
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.activityIndicatorView stopAnimating];
    });
}
複製代碼
  • 聲明週期方法
- (void)dealloc {
    // 移除掉添加通知
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
}
複製代碼

2.2.方法實現

- (AFActivityIndicatorViewNotificationObserver *)af_notificationObserver {
    // 經過運行時的關聯對象爲UIActivityIndicatorView添加了一個屬性:af_notificationObserver,這個屬性保存的就是上面看過的那個私有類
    AFActivityIndicatorViewNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver));
    if (notificationObserver == nil) {
        notificationObserver = [[AFActivityIndicatorViewNotificationObserver alloc] initWithActivityIndicatorView:self];
        objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return notificationObserver;
}

- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
    // 生成AFActivityIndicatorViewNotificationObserver對象,並經過關聯對象保存在擴展的屬性af_notificationObserver中,而後調用這個對象的綁定task的方法
    [[self af_notificationObserver] setAnimatingWithStateOfTask:task];
}
複製代碼

3.總結

能夠看到當咱們使用這個分類時,只須要經過接口暴露的方法傳入想要綁定加載菊花控件的task,在方法內部就會生成一個負責管理加載菊花控件的對象,並經過關聯對象保存。post

負責管理加載菊花控件的對象,會經過添加通知監聽task的開始與中止,來控制空間的展現與隱藏。ui

源碼閱讀系列:AFNetworkingatom

源碼閱讀:AFNetworking(一)——從使用入手spa

源碼閱讀:AFNetworking(二)——AFURLRequestSerialization3d

源碼閱讀:AFNetworking(三)——AFURLResponseSerializationcode

源碼閱讀:AFNetworking(四)——AFSecurityPolicyserver

源碼閱讀:AFNetworking(五)——AFNetworkReachabilityManager

源碼閱讀:AFNetworking(六)——AFURLSessionManager

源碼閱讀:AFNetworking(七)——AFHTTPSessionManager

源碼閱讀:AFNetworking(八)——AFAutoPurgingImageCache

源碼閱讀:AFNetworking(九)——AFImageDownloader

源碼閱讀:AFNetworking(十)——AFNetworkActivityIndicatorManager

源碼閱讀:AFNetworking(十一)——UIActivityIndicatorView+AFNetworking

源碼閱讀:AFNetworking(十二)——UIButton+AFNetworking

源碼閱讀:AFNetworking(十三)——UIImageView+AFNetworking

源碼閱讀:AFNetworking(十四)——UIProgressView+AFNetworking

源碼閱讀:AFNetworking(十五)——UIRefreshControl+AFNetworking

源碼閱讀:AFNetworking(十六)——UIWebView+AFNetworking

相關文章
相關標籤/搜索