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

堯少羽發表於2018-03-16

該文章閱讀的AFNetworking的版本為3.2.0。

這個分類可以為UIRefreshControl繫結一個task,然後根據task的載入狀態自動開始和結束重新整理。

1.介面檔案

/**
 為UIRefreshControl繫結指定的task
 */
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
複製程式碼

2.AFRefreshControlNotificationObserver私有類

2.1.屬性

/**
 儲存要繫結task的重新整理控制元件
 */
@property (readonly, nonatomic, weak) UIRefreshControl *refreshControl;
複製程式碼

2.2.方法

/**
 以指定重新整理控制元件初始化的方法
 */
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl;

/**
 為UIRefreshControl繫結指定的task
 */
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
複製程式碼

2.3.實現

  • 介面方法的實現
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl
{
    self = [super init];
    if (self) {
        // 用屬性儲存傳入的引數
        _refreshControl = refreshControl;
    }
    return self;
}

- (void)setRefreshingWithStateOfTask:(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) {
        // 獲取到傳入的重新整理控制元件
        UIRefreshControl *refreshControl = self.refreshControl;
        // 如果task的狀態是正在執行中
        if (task.state == NSURLSessionTaskStateRunning) {
            // 重新整理控制元件開始重新整理
            [refreshControl beginRefreshing];

            // 註冊通知監聽task的開始、完成和暫停
            [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task];
        // 如果task的狀態不是是正在執行中
        } else {
            // 重新整理控制元件停止重新整理
            [refreshControl endRefreshing];
        }
    }
}
複製程式碼
  • 通知回撥方法的實現
- (void)af_beginRefreshing {
    // 在主佇列非同步呼叫重新整理控制元件的開始重新整理
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.refreshControl beginRefreshing];
    });
}

- (void)af_endRefreshing {
    // 在主佇列非同步呼叫重新整理控制元件的停止重新整理
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.refreshControl endRefreshing];
    });
}
複製程式碼
  • 生命週期方法實現
- (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];
}
複製程式碼

3.方法實現

- (AFRefreshControlNotificationObserver *)af_notificationObserver {
    // 先通過關聯物件獲取為分類建立的屬性
    AFRefreshControlNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver));
    // 如果屬性為空
    if (notificationObserver == nil) {
        // 建立重新整理控制元件通知觀察者物件
        notificationObserver = [[AFRefreshControlNotificationObserver alloc] initWithActivityRefreshControl:self];
        // 通過關聯物件將建立的物件儲存到屬性中
        objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return notificationObserver;
}

- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
    // 獲取到重新整理控制元件通知觀察者物件併為之繫結task
    [[self af_notificationObserver] setRefreshingWithStateOfTask:task];
}
複製程式碼

4.總結

可以看到這個分類的實現基本和UIActivityIndicatorView+AFNetworking分類的實現一模一樣。都是依靠分類內部的私有類通過對繫結task相關屬性新增通知觀察,來控制重新整理控制元件的動作。

原始碼閱讀系列:AFNetworking

原始碼閱讀:AFNetworking(一)——從使用入手

原始碼閱讀:AFNetworking(二)——AFURLRequestSerialization

原始碼閱讀:AFNetworking(三)——AFURLResponseSerialization

原始碼閱讀:AFNetworking(四)——AFSecurityPolicy

原始碼閱讀: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

相關文章