【问题标题】:Why the CLLocationManager delegate is not getting called in iPhone SDK 4.0?为什么在 iPhone SDK 4.0 中没有调用 CLLocationManager 委托?
【发布时间】:2011-03-04 18:55:36
【问题描述】:

这是我的 AppDelegate 类中的代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = 1000;  // 1 Km
    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    [locationManager startUpdatingLocation];
}

这是我的 AppDelegate 类中的委托方法

    //This is the delegate method for CoreLocation
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{

        //printf("AppDelegate latitude %+.6f, longitude %+.6f\n", newLocation.coordinate.latitude, newLocation.coordinate.longitude);

}

它可以在 3.0, 3.1, 3.1.3 中运行,但它不能在 4.0 模拟器和设备中运行。

是什么原因?

【问题讨论】:

  • 在这里遇到同样的问题,你确定更新位置大约需要 40 秒?
  • 有人找到解决方案了吗???

标签: iphone core-location cllocationmanager cllocation


【解决方案1】:

我遇到了类似的错误,现在已解决。问题是在本地声明 locationManager 变量。将其声明为类变量,并确保直接或通过属性保留(如果使用 ARC,则为强)保留它。这样就解决了问题!问题是 de locationManager 变量被释放并且从未更新委托。代码如下:

.h 文件:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>


@interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
@private
    MKMapView *_mapView;
    CLLocationManager *_locationManager;
}

@property(nonatomic, strong) CLLocationManager *locationManager;

@end

.m 文件:

self.locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[_locationManager startUpdatingLocation];

希望对你有帮助。

【讨论】:

    【解决方案2】:

    您的委托中的-locationManager:didFailWithError: 是否曾经被调用过?我只是在想,也许您在某个时候拒绝访问位置数据,现在没有收到提示,但访问被拒绝了。

    【讨论】:

      【解决方案3】:

      我疯狂地试图弄清楚为什么只有几个使用 CLLocationManager 的类中的一个永远无法调用任何 CLLocationManagerDelegate 方法。

      事实证明:该类是从非主线程初始化的,因此它的 CLLocationManager 是在非主线程上创建的……它甚至可能是一个临时线程。无论如何,用下面的代码包装初始化我的类的调用就是让我的 CLLocationManager 委托方法被调用所需要的全部内容。

      dispatch_sync(dispatch_get_main_queue(), 
                          ^{
                               // create your class that will create a CLLocationManager here.
                           });
      

      所以底线:不要在除主线程之外的任何东西上创建 CLLocationManager,否则您将永远无法调用您的委托方法!我曾经知道这...只是很久...叹息。浪费了一天的时间来解决这个问题!由于我读过的所有 CLLocationManager SO 都没有提到这个,所以我把它贴在这里。希望它可以帮助某人!

      【讨论】:

      • 这也是我的解决方案。我不明白为什么这不在官方文档中,或者不难找到。
      【解决方案4】:

      您确定没有将位置管理器释放到某个地方吗?您的代码显示它已在 didFinishLaunching... 方法中分配,但随后被遗忘(尽管它仍被保留,因此应该仍然有效)。

      您是否看到初始弹出窗口询问您是否可以获取用户位置?

      【讨论】:

        【解决方案5】:

        将代码放在 viewController “被推送到 navigationController”中。

        我的代码是。

        在 SomeViewController.h 中

        #import <MapKit/MapKit.h>
        @interface SomeViewController : UIViewController<CLLocationManagerDelegate>{
        }
        @property (nonatomic, strong) CLLocationManager *locationManager;
        @end
        

        在 SomeViewController.m 中

        #import "SomeViewController.h"
        
        @implementation SomeViewController
        
        
        -(void)findLocation{
            if ([CLLocationManager locationServicesEnabled]) {
                if (!self.locationManager) {
                    self.locationManager = [[CLLocationManager alloc] init];
                    self.locationManager.delegate = self;
                    self.locationManager.distanceFilter = kCLDistanceFilterNone;
                    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
                    [self.locationManager startUpdatingLocation];
                }
            }
        }
        -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
            NSLog(@"didUpdateLocations");
        
            CLLocation *lo = [locations objectAtIndex:0];
            NSLog(@"latitude = %f, longitude = %f", lo.coordinate.latitude, lo.coordinate.longitude);
        
            [manager stopUpdatingHeading];
        }
        -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
            NSLog(@"didUpdateToLocation");}
        -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
            NSLog(@"didFailWithError");
            [manager stopUpdatingLocation];
        }
        

        我认为是ARC的问题,locationManager被释放了。

        【讨论】:

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