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

时间:2017-04-28 16:38:27

标签: swift multithreading grand-central-dispatch cllocationmanager nsthread

根据CLLocationManagerDelegate

的文件
  

从您启动相应位置服务的线程调用委托对象的方法。该线程本身必须有一个活动的运行循环,就像在应用程序的主线程中找到的那样。

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

无论如何,这解释了当CLLocationManagerDelegate没有收到来自CLLocationManager的后台线程中启动的任何事件时的issue

  

该线程本身必须有活动运行循环

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

this问题中建议了确保运行循环正在运行的合理解决方案,但作者暗示这是一种处理器的昂贵方法。

另外,根据线程documentation

  

线程在内存使用和性能方面对您的程序(和系统)造成实际成本

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

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

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

1 个答案:

答案 0 :(得分:4)

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

没有

只需将事件传递到主队列,并将任何工作分配给后台队列(如果它不重要)。其他任何事情都是很复杂的,没有什么好处。 CLLocationManager早于GCD,所以这是我们偶尔手动管理运行循环并从一个线程调度到另一个线程的日子里很有用的信息。 GCD摆脱了大部分内容,绝对是你应该使用的工具。让GCD使用dispatch_async处理它。

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