0

如果 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
      }
});

或者

创建“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
                });
}

编辑:在每个Call Api中,我使用的是NSOperationQueue

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

2 回答 2

2

我会建议使用 NSOperations 而不是。NSOperations为每个 API创建一个。创建一个NSOperatioQueue,添加NSOperations到队列并高枕无忧,而 iOS 负责决定并发运行多少操作以及所有其他与线程和内存相关的复杂任务 :)

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 个操作。

作为一名开发人员,您可能并不总是处于一个很好的位置来决定系统可以承受的最佳线程数是多少 :) 但操作系统总是可以有效地做到这一点。因此,始终建议尽可能将这些负担转移到操作系统上:)

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

我相信如果你对 JAVA 有任何经验,你一定遇到过 ExecutorPool 的概念。NSOperationQueue 与 ExecutorPool 为 JAVA 所做的完全一样 :)

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

我相信您知道您所有的 UI 操作都是在主线程中执行的,并且主线程使用 Main Queue 来调度事件。在 Main Queue 上执行冗长的操作并使其忙碌会导致非常糟糕的用户体验。

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

我想你现在知道你的问题的答案了:) 具体使用 [[NSOperationQueue alloc] init] 来解决你的情况。

于 2016-05-17T13:07:22.603 回答
0

首先,您应该阅读以下内容:GCD Practicum

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

于 2016-05-17T15:52:57.610 回答