为啥 AFNetworking POST 多部分请求必须在主队列上同步运行?

Posted

技术标签:

【中文标题】为啥 AFNetworking POST 多部分请求必须在主队列上同步运行?【英文标题】:Why AFNetworking POST Multi-Part Request has to sync run on main queue?为什么 AFNetworking POST 多部分请求必须在主队列上同步运行? 【发布时间】:2015-05-15 03:07:06 【问题描述】:

我检查了 POST 多部分请求的 AFNetworking 代码,令我惊讶的是它必须在主队列上同步运行,

- (BOOL)transitionToNextPhase 
    if (![[NSThread currentThread] isMainThread]) 
        dispatch_sync(dispatch_get_main_queue(), ^
            [self transitionToNextPhase];
        );
        return YES;
    
...

为 POST 多部分请求创建 AFHTTPBodyPart 时调用此方法

[manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) 
    [formData appendPartWithFileURL:filePath name:@"image" error:nil];
 success:^(AFHTTPRequestOperation *operation, id responseObject) 
    ...
 failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    ...
];

它实际上是在 GitHub issue #2006 上被询问和回答的“我认为那是因为主线程将用作同步点。(以确保操作以正确的顺序发生,即使它们在不同的线程上.)...”

我可以理解操作需要按顺序运行,但为什么在 主队列 中?我们不能只为它设置另一个专用队列吗?

我还向issue #2481添加了我的问题和一种相对简单的死锁重现方法

【问题讨论】:

【参考方案1】:

如果您在后台线程上,我可以想象在“当前”运行循环中调度NSInputStream(稍后在同一例程中查看)会出现问题。您通常不能只在后台线程上安排计时器、连接、流等,而不以某种方式保持运行循环(参见networkRequestThread)。此外,应用程序开发人员(通过appendPartWithInputStream)提供的输入流也可能存在微妙的问题,希望他的输入流也可以从主线程中使用。

我怀疑 Mattt 的结论是,在除主线程之外的任何线程上同步此行为将是大量工作。此外,将其从主线程中移出几乎没有什么好处(因为无论如何都不应该阻塞主线程)。

但是你应该create your own issue直接问作者。

【讨论】:

想想你的话,我觉得有道理。就像苹果文档说的“你永远不应该尝试从与拥有流的运行循环的线程不同的线程访问预定的流”所以让它在主线程中运行是我猜想的最简单的解决方案。顺便说一句,我没有打开我自己的问题 b/c,因为我已经表明问题被提出并关闭了,我只是没有完全得到答案。

以上是关于为啥 AFNetworking POST 多部分请求必须在主队列上同步运行?的主要内容,如果未能解决你的问题,请参考以下文章

使用 AFNetworking 的多部分 PUT 请求

AFNetworking 2.0 多部分请求正文空白

AFNetworking HTTP POST 上传图像在接近完成时停止

AFNetworking V2.0 中的多参数 POST

AFHttpSessionManager - 导致 org.codehaus.jackson.JsonParseException 的多部分 POST

AFNetworking:从文件发送图像