【问题标题】:Objective C: get location without delegate目标 C:在没有委托的情况下获取位置
【发布时间】:2014-06-11 15:12:03
【问题描述】:

我在 Objective C 中遇到问题(为 iPhone 编写应用程序)。我知道如何使用locationManager 及其代表。一旦我在locationManager 上调用startUpdatingLocation,它就会在位置更新时调用委托方法didUpdateToLocation。但问题是,这种方式现在适合我想做的事情。我有一个方法(在一个类中),如下所示:

@implementation SomeClass

   - (someType)getDbContentsOrderByDistance
   {
      ... //here I need the current location
      return dbContents;
   }

@end

现在这个函数从一个 sqlite 数据库中选择条目,按照它们到用户当前位置的距离排序。这就是为什么我需要这个函数中的位置。我在上面的方法中要做的是:获取位置,然后从数据库中选择东西并返回它。我知道我可以尝试访问locationManager.location.coordinate.longitude,但我知道在第一次位置更新到来之前,里面不会有任何有用的东西。而且我不想在之前(例如,在启动应用程序时)开始位置更新,因为如果我只需要一次位置,那将不是很有效。

我知道如何在位置更新到达时立即调用委托的方式来执行此操作。问题是我不知道如何将更新后的位置从那里获取到我上面的方法中。基本上我需要让方法“等待”直到第一次位置更新,然后继续使用该位置执行。

感谢您的帮助!

【问题讨论】:

    标签: ios objective-c delegates location


    【解决方案1】:

    简短的回答是,你不能。获取用户位置是一个异步过程,并且必须是一个异步过程。该设备必须启动各种硬件,如 GPS、蜂窝塔定位器和 WiFi 三角测量系统,从这些不同的设备获取输入,并将其合成到一个位置。这需要几秒钟的时间。

    Putz 关于启动计时器的建议是一个很好的建议。不过,我会添加一些内容。

    通常情况下,您从位置管理器获得的第一个读数非常糟糕,应该丢弃。您获得的第一个读数通常是 GPS 处于活动状态时的最后一次位置读数,并且会有一个过期的时间戳。该位置的准确度读数可能看起来相当不错,但这是一个谎言。我已经看到第一个位置读数偏离了几公里。您需要检查位置更新的时间戳,并丢弃任何超过 1 秒的读数。

    一旦您丢弃了过时的读数,前几次位置更新通常会非常糟糕,因为 GPS 尚未稳定下来。水平精度读数(实际上是一个“混乱圈”,或可能位置的半径)是一个大得离谱的值,有时是一公里或更多。同样,您需要编写位置管理器委托方法来丢弃太不准确的读数。我建议丢弃水平精度读数 >= 100 米的值。您可以容忍多少不准确取决于具体的称谓,但请注意不要让准确度要求过于准确。有时 GPS 拒绝安定下来。如果您需要 5 米的精度,则在整个应用程序运行期间您可能无法获得可接受的精度。 (如果您处于城市环境、建筑物或其他 GPS 信号干扰/阻塞较多的区域)

    一旦你最终得到一个足够准确的值,保存位置并将你的 locationAvailable 标志设置为 YES。

    请注意,您可以使用通知管理器来广播“找到一个好位置”消息,而不是计时器。任何需要位置信息的对象都可以注册您的通知,并在位置管理器获得可接受的位置读数时被调用。

    【讨论】:

      【解决方案2】:

      启动一个每秒触发一次的计时器,以调用您需要该位置的函数。检查该位置是否已设置。如果位置有效则终止计时器,否则让计时器继续并在一秒钟左右再次检查。

      知道位置是否有效的方法是在委托方法中。设置一个像locationAvailable = false 这样的全局变量。然后,当调用委托方法时,将该变量设置为 true。

      【讨论】:

        【解决方案3】:

        使用位置属性可以解决目的

        From apple documentation 位置 最近检索到的用户位置。 (只读) @property(readonly, nonatomic, copy) CLLocation *location

        如果没有检索到任何位置数据,则此属性的值为 nil。 在 iOS 4.0 及更高版本中,此属性可能在启动时包含更新的位置对象。具体来说,如果正在运行重要的位置更新并且您的应用已终止,则此属性会在您的应用重新启动时使用最新的位置数据进行更新(并且您创建一个新的位置管理器对象)。此位置数据可能比您的应用处理的最后一个位置事件更新。 检查存储在此属性中的位置的时间戳总是一个好主意。如果接收器当前正在收集位置数据,但最小距离过滤器很大,则返回的位置可能相对较旧。如果是,您可以停止接收器并重新启动它以强制更新。

        每当我创建位置管理器的新实例时,我都会在 location 属性中获得最新的位置值,并且由于我的距离过滤器未设置,因此它具有当前时间戳。这意味着我不必调用 startUpdatingLocation 并且我的数据是准确的。我还需要它来计算用户位置和地点之间的距离,这样如果它在范围内,我可以立即返回真或假。我发现这非常有用,因为我可以在 0.006 秒内获得位置并且很方便,并且仅从苹果文档中获得,但我仍然不知道这是否是最佳实践。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-28
          • 2023-03-10
          • 1970-01-01
          • 2013-09-11
          • 1970-01-01
          • 2012-07-24
          相关资源
          最近更新 更多