在后台线程上启动 CLLocationManager 是否明智?

Is it sensible to start `CLLocationManager` on a background thread?

根据 CLLocationManagerDelegate

的文档

The methods of your delegate object are called from the thread in which you started the corresponding location services. That thread must itself have an active run loop, like the one found in your application’s main thread.

我不清楚这是否意味着要在后台线程上接收位置管理器更新,我们必须在该后台线程上实例化位置管理器或简单地在该线程上调用 startUpdatingLocation() 方法。

无论如何,这解释了 issueCLLocationManagerDelegate 没有从在后台线程上启动的 CLLocationManager 接收任何事件时:

That thread must itself have an active run loop

如果我理解 运行 循环正确运行,所有 NSThreads 都用 运行 循环实例化,但 运行 循环只会 运行如果您将一些工作分配给线程,则为 ning。因此,要让 CLLocationManager 在后台线程上正确发送事件,我们需要将线程的 运行 循环设置为永久循环,以便它可以在 CLLocationManager 的调用到达时进行处理.

this 问题中提出了确保 运行 循环是 运行ning 的合理解决方案,但作者暗示这是一种处理器开销很大的方法。

另外,根据线程documentation

Threading has a real cost to your program (and the system) in terms of memory use and performance

我很欣赏无论如何我们都在使用大量线程,通过使用 Grand Central Dispatch,但 Grand Central Dispatch 可能在其内部线程管理中减轻了很多这种情况。

所以我的第一个问题是,是否值得设置一个具有连续 运行ning 运行 循环的后台线程,以便在后台线程,或者与将管理器留在主线程上相比,这会涉及不合理的额外处理量吗?

其次,如果值得的话,有没有使用 Grand Central Dispatch 来做到这一点的好方法。据我了解 documentation,Grand Central Dispatch 管理自己的线程,我们无法知道给定块将在哪个线程上执行。我想我们可以简单地执行通常的 运行 循环代码,使我们的 CLLocationManager 实例化是 运行 的任何线程的 运行 循环连续不断地循环,但这可能不会影响独立分配给 Grand Central Dispatch 的其他任务?

这是一个有点基于意见的问题,但我对此有很强的意见:D

没有

只需将事件传送到主队列,并将任何重要的工作分派到后台队列。任何其他事情都会带来很多复杂性,但收效甚微。 CLLocationManager 早于 GCD,因此在我们偶尔手动管理 运行 循环并且从一个线程分派到另一个线程很痛苦的日子里,这是有用的信息。 GCD 摆脱了其中的大部分,绝对是您应该为此使用的工具。让 GCD 处理它 dispatch_async.

您绝对不应该为这种事情设置自己的 NSThread。它们有时仍然是与 C++ 交互所必需的,但通常如果 GCD 可以处理某些事情,你应该放手,并尽可能避免 NSThread