Ios 目标C:在没有代表的情况下获得位置

Ios 目标C:在没有代表的情况下获得位置,ios,objective-c,delegates,location,Ios,Objective C,Delegates,Location,我在Objective C(为iPhone编写应用程序)中遇到了一个问题。我知道如何使用locationManager及其代理。在locationManager上调用startUpdatingLocation后,每当更新位置时,它都会调用委托方法DidUpdateLocation。但问题是,这种方式现在适合我想做的事情。我有一个方法(在类中)如下所示: @implementation SomeClass - (someType)getDbContentsOrderByDistance

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

@implementation SomeClass

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

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

我知道如何在位置更新到达时调用代理。问题是,我不知道如何将更新后的位置输入到上面的方法中。基本上,我需要让方法“等待”直到有第一个位置更新,然后继续使用该位置执行


谢谢你的帮助

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


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

简而言之,您不能。获取用户位置是一个异步过程,必须是一个异步过程。该设备必须启动各种硬件,如GPS、基站定位仪和WiFi三角测量系统,从这些不同的设备获取输入,并将其合成为一个位置。这需要几秒钟的时间

普茨关于启动计时器的建议很好。不过,我想补充几点

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

一旦你放弃了陈旧的读数,最初的几次位置更新往往非常糟糕,因为GPS还没有稳定下来。水平精度读数(实际上是一个“混乱圈”,或可能位置的半径)是一个荒谬的大值,有时是一公里或更长。同样,您需要编写location manager委托方法来丢弃太不准确的读数。我建议丢弃水平精度读数大于等于100米的值。你能容忍的不准确程度取决于具体的称谓,但要小心使准确度要求过于准确。有时GPS拒绝安定下来。如果您需要5米的精度,则在整个应用程序运行期间,您可能无法获得可接受的精度。(如果您所在的城市环境、建筑物或其他区域存在大量GPS信号干扰/障碍物)

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


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

使用location属性可以解决此问题

位置最近检索到的用户位置。(只读) @属性(只读、非原子、复制)CLLocation*location

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

每当我创建location manager的新实例时,我都会在location属性中获取location的最新值,并且由于未设置距离过滤器,因此它具有当前时间戳。这意味着我不必致电startUpdatingLocation,我的数据是准确的。我还需要它来计算用户位置和某个位置之间的距离,以便在该范围内立即返回true或false。我发现这非常有用,因为我可以在0.006秒内找到位置,而且非常方便,而且只从苹果的文档中获得,但我仍然不知道这是否是一个最佳实践