我正在使用CLLocationManager
类。我有一个简单的类方法来捕获位置
+(void)captureLocation{
mLocationManager = [[CLLocationManager alloc]init];
mLocationManager.delegate = (id<CLLocationManagerDelegate>)self;
mLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
[mLocationManager startUpdatingLocation];
}
我也有CLLocationManager
的委托方法
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
}
现在我想在我的viewDidLoad
中调用这个方法
- (void)viewDidLoad
{
[super viewDidLoad];
[myclass captureLocation];
}
调用该方法但未调用委托方法。
我还有其他类方法,如果我再次尝试调用该方法,则会调用captureLocation
方法,但不会调用委托方法。这是另一个类方法
+(void)initialize{
[self captureLocation];
}
请帮助我找出为什么委托方法没有被调用,因为我是这个领域的新手。提前致谢。
还要知道iOS 8的CoreLocation权限已更改。如果您未请求新的权限授权,则CoreLocation不会执行任何操作。它安静地失败,因为从不调用委托方法。
我意识到这个问题是在2013年被问到的,但是如果你遇到类似的问题而没有调用委托方法,那么这篇文章非常有帮助:
http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
虽然文章非常详细且篇幅很长,但实际的代码修复可能与此相同:
if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[locationManager requestWhenInUseAuthorization];
}
并且您必须向info.plist添加一个值,这是要在权限警报中显示的消息。看屏幕抓取。
密钥:NSLocationWhenInUseUsageDescription
价值:需要位置才能找到你所在的位置(你可以根据需要改变它)
你是在一个类方法中设置delegate
的CLLocationManager
(即一个前缀为+
而不是-
)。所以,当你在该类方法中引用self
时,那就是类,而不是类的实例。所以,你试图将delegate
设置为类而不是类的实例。
那不行。委托方法是实例方法,而不是类方法。 (这可能是为什么你在分配CLLocationManagerDelegate
时必须使用delegate
演员。)
您必须实际实例化您实施CLLocationManagerDelegate
方法的任何类。如果您不想将该实例绑定到特定视图控制器,则可以使用单例模式。无论如何,您可以将位置管理器的委托设置为指向该类的该实例。
例如,如果您希望它是单身人士:
// MyClass.h
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
+ (instancetype)sharedManager;
- (void)startCapture;
- (void)stopCapture;
@end
和
// MyClass.m
#import "MyClass.h"
#import <CoreLocation/CoreLocation.h>
@interface MyClass () <CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;
@end
@implementation MyClass
+ (instancetype)sharedManager
{
static id sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (void)startCapture
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
- (void)stopCapture
{
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
// ...
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// ...
}
@end
然后,
- (void)viewDidLoad
{
[super viewDidLoad];
[[MyClass sharedInstance] startCapture];
}
在+方法中调用self
会将您的委托设置为nil,因为这意味着ClassName
与[[ClassName alloc] init]
一样。
你需要:
mLocationManager.delegate = mLocationManager
代替
mLocationManager.delegate (id<CLLocationManagerDelegate>)self;
在ios6
中,locationManager:didUpdateToLocation:fromLocation:
已弃用,因此您需要在代码中添加其他方法...
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// this method get called in ios7 .
}
在iOS -8中需要做一些更改: