【问题标题】:Why use async HTTP request over sync HTTP in a separate thread?为什么在单独的线程中使用异步 HTTP 请求而不是同步 HTTP?
【发布时间】:2012-08-07 10:03:49
【问题描述】:

我知道每种工作方式之间的区别,但我想从性能角度了解(iphone 内的资源)。

假设我发送了一个异步请求并等待调用委托。这不会锁定我的执行线程。但是这样做与在另一个线程中使用 GCD 发送同步请求有什么区别。

像这样:

dispatch_queue_t findPicsQueue;

findPicsQueue = dispatch_queue_create("FindPicsQueue", NULL);


dispatch_async(findPicsQueue, ^{

    NSData *theResponse = [NSURLConnection sendSynchronousRequest:theRequest
                                                        returningResponse:&response
                                                                    error:&error];

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;

    if (error) {
       NSLog(@"Error: %@",error)
    }

    if (httpResponse.statusCode == 200) 
    {
        [self parseXMLFile:theResponse]; // Parses Data and modifies picturesFound

        for (PictureData *tmp in picturesFound) {
            NSLog(@"%@",tmp);
        }          
    }  
}

它不会锁定我的界面,因为它没有在主线程中执行,但它会锁定这个特定的线程。而且我也认为 GCD 会同时运行队列。

提前致谢。我真的很想澄清这个问题。

【问题讨论】:

  • GCD 不会在这个队列上同时运行,因为你已经创建了一个 serial 队列。对于并发队列,您必须传入 DISPATCH_QUEUE_CONCURRENT 参数。但是,它可以与 other 队列并行运行。
  • @borrrden 如果我理解正确,这个队列将在设备上同时运行,我添加到这个队列的其他块或任务将连续运行,然后我只有一个块,所以它不相关.根据文档:您可以根据需要创建任意数量的串行队列,并且每个队列相对于所有其他队列同时运行。换句话说,如果您创建四个串行队列,每个队列一次只执行一个任务,但最多仍可以同时执行四个任务,每个队列一个。
  • @borrrden 哈哈,原来不是这么说的!但没关系,我们的意思是一样的。
  • @borrrden 对原始问题并不重要,但要澄清一下:iOS 目前不支持 DISPATCH_QUEUE_CONCURRENT(仅限 Mac OS X 10.7 或更高版本),因此手动创建的队列是串行的。不过,全局队列是并发的。见Concurrency Programming Guide
  • @RobertRyan 网上各种消息称 iOS 5 也支持它,在 queue.h 中它甚至被标记为从 iOS 4.3 开始可用

标签: ios concurrency nsurlconnection grand-central-dispatch


【解决方案1】:

如果你使用NSURLConnectionsendAsynchronousRequest,那么几乎所有的处理都在主线程上进行,特别是XML解析将在主线程上完成。但是,您的代码示例使用不同的线程进行处理。

如果您的 iPhone 或 iPad 处理器具有两个内核,则此差异是相关的。然后 XML 解析可以与主线程上的一些 UI 活动并行运行(在您的示例中)。所以它可以比在主线程上运行所有东西更早完成(sendAsynchronousRequest 方法)。

对于只有一个内核的旧设备,一次只能运行一个线程,这两种方法的行为应该几乎相同。

【讨论】:

  • 主胎面上的异步不会阻止任何东西,对吧?这意味着它只是等待通知执行以下任务,同时执行其他任务。另一个踏板上的同步迫使该队列等待,我认为这意味着它的行为就像它不断运行一样。如果我有 2 个处理器,主队列正在执行 gui 的东西,另一个正在执行这个,但它是否算作连续处理这个任务直到它完成?第二核上的并发是怎么修改的?
  • 主线程上的异步请求最初不会阻塞任何东西,直到数据准备好。它必须等到主线程空闲(没有要处理的 UI 活动),然后在 XML 解析期间阻塞所有 UI 活动。所以如果它需要很长时间,它是相关的。单独的 GCD 队列上的同步请求一旦开始就会或多或少地连续工作。 或多或少因为网络流量当然涉及等待下一个网络包。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多