美文网首页
AFNetworking 2.x, AFNetworking 3

AFNetworking 2.x, AFNetworking 3

作者: Ian_ | 来源:发表于2017-11-16 18:39 被阅读138次

AFN 2.0

AFHTTPRequestOperationManager

- (AFHTTPRequestOperation *)GET:(NSString *)URLString
                     parameters:(id)parameters
                        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure];

    [self.operationQueue addOperation:operation];

    return operation;
}

就 get 方法而言, 它获取了一个 operation, 并将 operation 添加到self.operationQueue, 我们先不去看获取operation 的过程到底发生了什么, 首先很明确的是, 每次网络请求都会在一个非主线程中执行。

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
                                                    success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                                    failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = self.responseSerializer;
    operation.shouldUseCredentialStorage = self.shouldUseCredentialStorage;
    operation.credential = self.credential;
    operation.securityPolicy = self.securityPolicy;

    [operation setCompletionBlockWithSuccess:success failure:failure];
    operation.completionQueue = self.completionQueue;
    operation.completionGroup = self.completionGroup;

    return operation;
}

这段代码是获取 operation , 可以清晰的看出 AFHTTPRequestOperation 是 NSOperation 的一个子类, 成功和失败是在 自定义的 operation 中回调的.
再看 setCompletionBlockWithSuccess 发生了什么,

- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                              failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    self.completionBlock = ^{
        // 由于代码过长, 具体参考 AFHTTPRequestOperation.m 107 行.
    };
}

可以清晰看出, 在操作完成的时候在操作里面通过判断 error, 来确定返回成功还是失败。
这就是一个完成一个请求的回调, 请求的具体过成是在其父类 AFURLConnectionOperation 中完成的, AFURLConnectionOperation 继承自 NSOperation, 在重写的 start 方法中, 执行了operationDidStart 方法:

- (void)operationDidStart {
    [self.lock lock];
    if (![self isCancelled]) {
        self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];

        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        for (NSString *runLoopMode in self.runLoopModes) {
            [self.connection scheduleInRunLoop:runLoop forMode:runLoopMode];
            [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
        }

        [self.outputStream open];
        [self.connection start];
    }
    [self.lock unlock];

    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidStartNotification object:self];
    });
}

ok, 在operationDidStart方法中, 初始化了self.connection, 并执行了 start, 后面的处理主要依赖self.connection 代理的回调, 包括进度错误等, 那么具体流程大概就已经清楚。

这大概就是 AFHTTPRequestOperationManager 基于 NSURLConnection 的一次 get 网络请求, 其他同理。

为了保证每次的网络请求的回调都可以接收到, 使用唯一的线程, 通过启动 runloop, 来保证线程不退出, 具体: AFURLConnectionOperation.m 167 行。

AFN 3.0

AFURLSessionManager
NSURLSession对于文件下载做了优化。

 (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(id)parameters
                     progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                      success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                      failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{

    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
                                                        URLString:URLString
                                                       parameters:parameters
                                                   uploadProgress:nil
                                                 downloadProgress:downloadProgress
                                                          success:success
                                                          failure:failure];

    [dataTask resume];

    return dataTask;
}

同样从 get 方法入手, 可以看出是获取到一个 NSURLSessionDataTask, 并开始 task, 和afn2.0思路相似。

我们继续往里面看,

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                               uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
                             downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
                            completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler {

    __block NSURLSessionDataTask *dataTask = nil;
    url_session_manager_create_task_safely(^{
        dataTask = [self.session dataTaskWithRequest:request];
    });

    [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];

    return dataTask;
}

dataTask 在这一步已经获取到了, 下面的addDelegateForDataTask等是为了获取到进度和完成的回调。

self.operationQueue = [[NSOperationQueue alloc] init]; self.operationQueue.maxConcurrentOperationCount = 1;

self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until it exits.

苹果 api 解释, 所以这里就不需要单例线程来保证回调, 因为他根本不会主动走 dealloc。

afn3.0 里的 task 就相当于 afn2.0 里面的 operation, 具体的实现思路大体相同。

相关文章

网友评论

      本文标题:AFNetworking 2.x, AFNetworking 3

      本文链接:https://www.haomeiwen.com/subject/uoewattx.html