前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AFNetworking源码探究(二十五) —— UIKit相关之UIRefreshControl+AFNetworking分类

AFNetworking源码探究(二十五) —— UIKit相关之UIRefreshControl+AFNetworking分类

原创
作者头像
conanma
修改2021-09-03 18:03:57
3840
修改2021-09-03 18:03:57
举报
文章被收录于专栏:正则正则

回顾

上一篇主要分析了UIProgressView+AFNetworking分类,主要实现了上传任务和下载任务与进度之间的绑定。这一篇主要分析UIRefreshControl+AFNetworking这个分类。


接口API

下面看一下接口API

代码语言:javascript
复制
/**
 This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task.
 */
@interface UIRefreshControl (AFNetworking)

///-----------------------------------
/// @name Refreshing for Session Tasks
///-----------------------------------

/**
 Binds the refreshing state to the state of the specified task.
 
 @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
 */
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;

@end

该类为UIKit框架的UIRefreshControl类添加方法。 根据会话任务的加载状态,此类别中的方法支持自动开始和结束刷新。

该接口就一个方法,将任务状态和刷新状态进行了绑定。


通知观察者类

在.m实现中,大家会发现不仅是这个AFNetworking分类,还有一个通知贯彻者类AFRefreshControlNotificationObserver。这个通知观察者类起到观察任务状态的作用,并且.h文件中那个方法的接口,可以进行了消息的转发,最后在AFRefreshControlNotificationObserver中进行了处理。

下面我们先看一下这个通知观察者类接口。

代码语言:javascript
复制
@interface AFRefreshControlNotificationObserver : NSObject

@property (readonly, nonatomic, weak) UIRefreshControl *refreshControl;

// 用于初始化
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl;

// 用于.h中方法的转发实现
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;

@end

AFNetworking runtime绑定观察者

这里就是利用runtime给AFNetworking类绑定观察者,在里面实例化了AFRefreshControlNotificationObserver并进行了绑定。

代码语言:javascript
复制
- (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;
}

// 初始化观察者类
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl
{
    self = [super init];
    if (self) {
        _refreshControl = refreshControl;
    }
    return self;
}

接口的转发实现

转发实现主要采用下面这个方法

代码语言:javascript
复制
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
    [[self af_notificationObserver] setRefreshingWithStateOfTask:task];
}

这就转发到了观察者类中进行了实现。

代码语言:javascript
复制
- (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];

    if (task) {
        UIRefreshControl *refreshControl = self.refreshControl;
        if (task.state == NSURLSessionTaskStateRunning) {
            [refreshControl beginRefreshing];

            [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];
        } else {
            [refreshControl endRefreshing];
        }
    }
}

这里首先移除了开始、暂停和完成的通知,然后进行了判断,如果任务存在,且任务的状态正在运行,那么就添加开始、暂停和完成的通知。如果任务的状态不是在运行,那么就调用方法停止刷新[refreshControl endRefreshing]

下面看那几个通知实现的方法。

代码语言:javascript
复制
- (void)af_beginRefreshing {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.refreshControl beginRefreshing];
    });
}

- (void)af_endRefreshing {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.refreshControl endRefreshing];
    });
}

后记

本篇主要讲述了UIRefreshControl+AFNetworking这个分类,将刷新状态和任务状态进行了绑定和同步。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 回顾
  • 接口API
  • 通知观察者类
  • AFNetworking runtime绑定观察者
  • 接口的转发实现
  • 后记
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档