使用NSOperationQueue,如何添加到后台队列而不是main,以及控制操作量如何工作?

Dou*_*ith 10 concurrency objective-c nsoperation nsoperationqueue ios

我很喜欢,NSOperationQueue但我有一些问题需要了解它的某些部分.

objc.io的第二期中,他们回顾了NSOperationQueue,并提到它有两种队列,即主线程上运行的主队列和后台队列.他们提到你可以访问主队列,[NSOperation mainQueue]然后添加操作它.

  • 你通常不想这样做,对吗?如果它在主线程上运行,它是否会阻止主线程执行其他任务?它不会与其他任务同时运行吗?

它还提到你可以通过创建NSOperation的实例(潜在的子类)来添加到后台队列(我理解会更好?).

  • 我是否保存了为操作创建的NSOperationQueue的引用,以便创建更多操作?我假设没有像背景队列那样的单例mainQueue,那么如何管理向后台队列添加任务呢?

它还提到您可以控制与maxConcurrentOperationCount属性同时运行的操作量.

  • 我知道你通常把它设置为NSOperationQueueDefaultMaxConcurrentOperationCount,但如果我手动将它设置为一个特定的数字,它是否对应于一次可以运行的最大线程数?例如,如果iPhone上的处理器可以同时运行4个线程并且我将该属性设置为8,会发生什么?

Rob*_*Rob 18

你问:

你通常不希望[添加操作mainQueue],对吗?如果它在主线程上运行,它是否会阻止主线程执行其他任务?它不会与其他任务同时运行吗?

是的,您永远不会想要在主队列中添加任何缓慢的内容.但这并不意味着您不使用主队列.对于某些操作(例如UI更新),这是至关重要的.

典型的模式是为要在后台运行的任务创建操作队列,但如果您随后需要执行需要在主队列上运行的操作(例如UI更新,更新模型等),会继续这样做,例如:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperationWithBlock:^{
    // do some time consuming stuff in the background

    // when done, you might update the UI in the main queue

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // update the UI here
    }];
];
Run Code Online (Sandbox Code Playgroud)

你问:

我是否保存对NSOperationQueue我为操作创建的引用,以便创建更多操作?我假设没有像mainQueue那样的背景队列单例,那么如何管理向后台队列添加任务呢?

是的,如果您想稍后向同一队列添加更多操作,是的,您希望维护对该队列的引用.您可以通过将其添加到应用程序委托,某个中央视图控制器或单例来完成此操作.

但是,是的,没有用于后台队列的内置单例(因为可以想象,对于不同的操作可以有不同的队列,例如一个用于网络操作,一个用于图像处理等).但是,如果需要,您可以为每种类型的每个队列编写自己的单例.

你也问:

我知道你通常把它设置为NSOperationQueueDefaultMaxConcurrentOperationCount,但如果我手动将它设置为一个特定的数字,它是否对应于一次可以运行的最大线程数?例如,如果iPhone上的处理器可以同时运行4个线程并且我将该属性设置为8,会发生什么?

应该设置maxConcurrentOperationCount为您认为适合队列类型的任何内容.对于网络操作队列,通常不会超过4,但对于其他类型的队列,您可能很容易拥有更多.我相信最多有64个工作线程(并发队列因为需要线程而自行使用).

如果您尝试使用更多,则在工作线程可用之前,应用程序将不会启动您的操作.不过,Apple建议不要使用所有工作线程.因此,请使用适合您队列功能的合理数字.坦率地说,操作队列优于调度队列的一个优点是,您可以限制在任何给定时间将使用的最大工作线程数,以更好地管理设备的有限资源.


参考