AFNetworking的成功/失败块是否在主线程上调用?

15 浏览
0 Comments

AFNetworking的成功/失败块是否在主线程上调用?

AFNetworking是否在主线程上调用完成块?还是在后台调用,需要我手动将UI更新调度到主线程上?

使用代码而非文字,这是来自AFNetworking文档的示例代码,其中调用NSLog的部分被UI更新替换:

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    self.label.text = JSON[@"text"];
} failure:nil];

是否应该改为这样写?

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.label.text = JSON[@"text"];
    });
} failure:nil];

0
0 Comments

AFNetworking的成功/失败回调默认是在主线程上执行的。但是,如果你在AFHTTPRequestOperation上显式地设置了队列,它们就会在指定的队列上执行。这个逻辑在AFHTTPRequestOperation.m文件中的setCompletionBlockWithSuccess:failure方法中可以看到。

具体的代码如下:

self.completionBlock = ^{
    if (self.error) {
        if (failure) {
            dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
                failure(self, self.error);
            });
        }
    } else {
        if (success) {
            dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{
                success(self, self.responseData);
            });
        }
    }
};

这段代码首先检查了self.error是否存在,如果存在则执行failure回调。在执行failure回调时,它会使用dispatch_async将回调块放入self.failureCallbackQueue队列中,如果self.failureCallbackQueue为空,则使用dispatch_get_main_queue()获取主队列。

接着,代码检查了self.error是否为nil,如果是nil,则执行success回调。在执行success回调时,它也使用dispatch_async将回调块放入self.successCallbackQueue队列中,如果self.successCallbackQueue为空,则同样使用dispatch_get_main_queue()获取主队列。

这样,无论是执行failure回调还是success回调,都会在主线程上执行。

需要注意的是,作者在评论中提到“Good to know probably should have checked and not assumed they just executed them on the same thread as the request”。这说明在使用AFNetworking时,我们不能假设成功/失败回调会在与请求相同的线程上执行,需要根据实际需求来设置回调执行的线程。

0
0 Comments

在AFNetworking 2中,AFHTTPRequestOperationManager类有一个completionQueue属性,用于处理请求操作的completionBlock的调度队列。如果completionQueue为NULL(默认值),则使用主队列。

在AFNetworking 3中,completionQueue属性被移动到AFURLSessionManager类(AFHTTPSessionManager是其子类)。该属性用于处理completionBlock的调度队列。如果completionQueue为NULL(默认值),则使用主队列。

根据以上内容,可以得出AFNetworking的success/failure blocks默认是在主线程中调用的。如果想要在其他线程中调用这些blocks,可以通过设置completionQueue属性来实现。

以下是解决方法的示例代码:

在AFNetworking 2中:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

在AFNetworking 3中:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

设置completionQueue属性为其他队列,即可在其他线程中调用success/failure blocks。

0
0 Comments

AFNetworking是一个在iOS和macOS平台上使用的网络请求框架,它提供了一种简单的方式来处理网络请求和数据响应。然而,有人提出了一个问题:AFNetworking的成功/失败回调方法是在主线程上调用的吗?

根据大家的解释,这个问题出现在AFNetworking的源代码中。为了解决这个问题,可以使用以下方法:

对于AFNetworking 2.xx版本,可以按照以下步骤操作:

1. 使用dispatch_queue_create函数创建一个自定义的串行队列,指定一个名称和DISPATCH_QUEUE_SERIAL标志。

2. 初始化AFHTTPRequestOperation对象,将请求作为参数传入。

3. 使用setCompletionQueue方法将自定义队列设置为AFHTTPRequestOperation对象的completionQueue属性。

代码示例:

// 创建一个自定义的串行队列
dispatch_queue_t myQueue = dispatch_queue_create("com.CompanyName.AppName.methodTest", DISPATCH_QUEUE_SERIAL);
// 初始化AFHTTPRequestOperation对象
operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
// 将自定义队列设置为completionQueue属性
[operation setCompletionQueue:myQueue];

对于AFNetworking 3.xx版本,可以按照以下步骤操作:

1. 初始化AFHTTPSessionManager对象。

2. 使用setCompletionQueue方法将自定义队列设置为AFHTTPSessionManager对象的completionQueue属性。

代码示例:

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
// 将自定义队列设置为completionQueue属性
[self setCompletionQueue:myQueue];

通过以上步骤,可以将成功/失败回调方法的执行线程设置为自定义的串行队列,从而实现在指定的线程上调用这些方法。这样可以更好地控制和管理回调方法的执行环境,提高代码的可维护性和可扩展性。

0