并发vs串行队列,用于在iOS中执行大量服务器请求

时间:2016-05-17 12:53:13

标签: ios objective-c grand-central-dispatch objective-c-blocks concurrent-queue

如果iOS应用程序必须在后台发出数百个服务器请求并将结果保存在本地移动数据库中,哪种方法在性能方面会更好(更少崩溃)?

将所有请求作为全局背景队列中的1个块传递

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    for (i=0;i<users;i++)
      {
        Call Api 1
        Call Api 2
        Call Api 3
      }
});

OR

创建'n'个用户串行队列,并将所有3个api调用作为每个串行队列中的单个块添加。

for (i=0;i<users;i++)
{
    dispatch_queue_t myQueue = dispatch_queue_create([[users objectAtIndex:i] UTF8String], DISPATCH_QUEUE_SERIAL);
              dispatch_async(myQueue, ^{
                   Call Api 1
                });
              dispatch_async(myQueue, ^{
                   Call Api 2
                });
              dispatch_async(myQueue, ^{
                   Call Api 3
                });
}

修改:在每个致电Api 中,我使用 NSOperationQueue

queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {..}

2 个答案:

答案 0 :(得分:2)

我建议使用NSOperations。为每个API创建一个'n'NSOperations一个。创建一个NSOperatioQueue,将NSOperations添加到队列中,然后坐下来放松,而iOS负担决定同时运行多少操作以及所有其他与线程和内存相关的复杂任务:)< / p>

GCD和NSOperations之间的主要区别在于能够暂停和恢复操作:)如果GCD一旦提交操作必然会发生,并且你无法跳过它们或暂停它们:)

在GCD中添加多个操作之间的依赖关系是很麻烦的,因为在NSOperations中添加依赖项和优先化任务只是几个语句的问题:)

修改

根据您的编辑,您已经在为每个API使用NSOperation。因此,绝对不需要再次调用dispatch_async中的NSOperations :)而是考虑创建一个NSOperationQueue并将这些NSOperations添加到队列中:)

您的评论质量保证

1. 如果我每次创建新的NSOperationQueue而不是将NSOperations添加到单个NSOperationQueue怎么办?

为每个NSOperation创建一个单独的队列绝不是一个好主意:)

建议NSOperationQueue只是为了减少手动多线程所必须承担的复杂功能:)

当您向NSOperationQueue提交NSOperation时,您可以指定NSOperationQueue可以执行的并发操作数。

请注意,它只是一个上限值:)如果指定允许的最大并发操作数为10,则意味着当iOS具有内存和CPU周期等资源时,它可以执行10次操作。

您作为开发人员可能并不总是能够确定系统可以承受的最佳线程数量,但OS可以始终高效地执行此操作。因此,最好尽可能在OS上转移这些负担:)

但是如果你想为每个API调用创建一个单独的线程而不是创建一个单独的队列,你可以考虑通过调用[NSOperation start]来单独执行NSOpertaions。为每个NSOperation创建一个NSOperationQueue是开销。

我相信如果您对JAVA有任何经验,那么您必须遇到ExecutorPool概念。 NSOperationQueue完全执行ExecutorPool为JAVA所做的事情:)

2. 我应该使用[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] ..而不是[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init]

我相信您知道所有UI操作都在主线程中执行,主线程使用主队列来分派事件。在主队列上执行冗长的操作并使其保持忙碌将导致非常糟糕的用户体验。

在主队列上调用100个API可能会导致用户卸载您的应用并给出最差评分:)

我想你现在知道你现在的问题的答案:)为你的情况特别使用[[NSOperationQueue alloc] init]。

答案 1 :(得分:0)

首先你应该读一下:GCD Practicum

其次,你不应该在这里推出自己的解决方案。而是使用AFNetworking,并根据需要发出请求。它已经设置了自己的操作队列,因此您无需处理。然后set the maximum number of concurrent requests到您手动调整的某个值。从四开始。