【问题标题】:Why is my CLLocationmanager delegate not getting called?为什么我的 CLLocationmanager 委托没有被调用?
【发布时间】:2011-04-13 12:16:41
【问题描述】:

我在 sim 卡或设备上都没有收到任何位置回调。我已经调用了这段代码:

- (void)startLocationCallbacks: (NSObject*) ignore
{
  locationManager.delegate = self;
  locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
  locationManager.distanceFilter = MINIMUM_METERS;

  [locationManager startUpdatingLocation];
  NSLog(@"[DEBUG] [locationManager startUpdatingLocation] (%@, %@)", locationManager, locationManager.delegate);
}

并在两者的顶部记录语句

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

但是没有一个日志语句被调用。我的应用启用了位置通知(如“设置”中所示,加上我说“允许”。)

我没有收到位置更新的可能原因有哪些?

配置/其他信息:

  • 我已分配 locationManager,并将其保存在一个保留属性中。
  • 我已调用 startUpdatingLocation
  • 我使用的是 4.1 SDK
  • 运行 4.1 的 Sim 和 iPod-touch(第 2 代)和 iPhone-3 都存在问题
  • 位置通知在我的应用中是允许的(两者都显示在“设置”中,因为我在警报中单击了“允许”。)
  • 我以前曾成功使用过 CLLocationManager(在许多运输应用程序中!)这对我来说真的是一个令人毛骨悚然的事情。

谢谢!

【问题讨论】:

  • 注意:我见过其他几个类似的 SO 问题,它们没有帮助。整个“打开你的 wifi”、“不要使用 sim”等等,在这里都不适用。反正我不能说。我希望找到一份我可能无法收到回调的所有原因的列表,以便我可以检查它们。谢谢!
  • 另一个线索:我在“设置”中关闭了位置通知,试图让它再次询问我。不问。此外,没有“用户被拒绝”错误 (didFailWithError:...) 就好像我的位置管理器没有启动一样。或者不承认我是代表。当我检查 locationManager.delegate 时,这是正确的。咕噜咕噜咕噜咕噜!
  • @vfn:尝试了你的技巧(将该代码挂钩到测试按钮),我的回调被调用并执行预期的操作。所以现在最大的问题是:什么会触发我的位置管理器向我发送有效位置或错误? (,我的 didUpdateLocation 和 didFailWithError 例程都没有被调用。)
  • 将精度改为最佳并移除距离过滤器。
  • @MaxMacLeod:症状相似,但根本原因不同。这个问题更恰当地是“为什么我的已发布变量不能继续起作用?”而这个更像是“为什么我的动作没有放在一个永远不会得到任何时间的线程上?” :)

标签: iphone cllocationmanager


【解决方案1】:

哇!好的,我找到了。

事实证明,使CLLocationManager 不触发位置回调的方法之一是在非主线程中进行所有设置。当我将设置例程移至 performSelectorOnMainThread 时,一切都按预期工作。

真是一场噩梦!

希望这个答案对其他人有所帮助...

编辑/澄清:

原来,我有这样的东西:

- (BOOL) appDidFinishLaunchingWithOptions: (NSDictionary*) options
{
     // ...[app setup, snip]
    [NSThread detachNewThreadSelector: @selector(postLaunchSetupThread) toTarget: self withObject: nil];
}

- (void)postLaunchSetupThread
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    // ...[other setup, snip]
    [self setupLocationManager];
    [pool release];
}

- (void)setupLocationManager
{
     self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
     [myLocationManager startLocationUpdates];
}

但是在线程中调用setupLocationManager 阻止了回调。所以我的解决方法是移动这条线

[self setupLocationManager];

退出线程并返回appDidFinishLaunchingWithOptions

【讨论】:

  • 感谢您的帮助 - 为我节省了数小时的疯狂尝试。 CLLocationManager 确实不喜欢在主线程之外创建。
  • 我想弄清楚这一点快疯了!非常感谢!
  • 你是救生员!花了一整天的时间在这个上拉我的头发......谢谢!
  • 主线程!!作品!谢谢。把我的头撞在这个上面30分钟。这也解决了我的问题。
【解决方案2】:

实际上你也可以从另一个线程运行它。 来自 Apple 文档:

您的位置管理器对象的配置必须始终发生在 具有活动运行循环的线程,例如应用程序的 main 线程。

只需确保您的运行循环在该线程上运行,并且 CLLocationManager 事件已被调度。 更多关于运行循环: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

【讨论】:

  • 真(+1),我应该在我的回答中提到这一点——但重点是:您不能将位置管理器设置为未运行的线程并期望它执行回调。解决方案包括 (a) 不要在单独的线程中设置它和 (b) 确保您的单独线程的 runloop 正在运行。
  • 我试图让它在一个正在运行的运行循环的线程上工作,并且仍然没有调用委托方法。你能提供一个可行的示例实现吗?
【解决方案3】:

//看看这个 //...CLLocationManager 没有正确调用委托方法

//...经过大量研发后,我使用了一种称为“的看门狗方法”

https://stackoverflow.com/questions/7156920/didupdatetolocation-doesnt-gets-called-immediately/14605889#14605889

【讨论】:

  • 这是一个不同的情况,问题是关于代表根本没有被调用。你提供的链接是关于时间的。奥利有正确的答案
【解决方案4】:

适用于 iOS 8

1) 我在初始化位置管理器后放置了这些行。

if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [self.locationManager requestAlwaysAuthorization];
}

2) 我将 NSLocationAlwaysUsageDescription 添加到 plist 并将其设置为字符串并添加了一条消息。 3) 在我的目标中,我点击了 Capabilities 选项卡,然后打开了 Background Modes 并选中了“Location Updates”和“Uses Bluetooth LE Accessories”

这对我有用

【讨论】:

    【解决方案5】:

    在我的情况下,这是因为我的设备无法确定位置 - 当我待在室内时,GPS 信号不可用且 wi-fi 也断开连接,因此位置管理器无法接收任何位置数据,并且从未呼叫过委托人.

    一旦我连接了 wi-fi,它就可以工作了(我想在这种情况下搬到户外也应该可以解决问题,但有时这不是很方便的方式 :))

    【讨论】:

      猜你喜欢
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多