我正在使用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];
}
请帮助我找出为什么委托方法没有被调用,因为我是这个领域的新手。提前谢谢。
答案 0 :(得分:10)
另请注意,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
价值:需要位置才能找到你所在的位置(你可以根据需要改变它)
答案 1 :(得分:5)
您要在类方法中设置delegate
的{{1}}(即一个前缀为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
答案 2 :(得分:0)
在+方法中调用self
会将您的委托设置为nil,因为它与ClassName
中的[[ClassName alloc] init]
相同。
你需要:
mLocationManager.delegate = mLocationManager
而不是
mLocationManager.delegate (id<CLLocationManagerDelegate>)self;
答案 3 :(得分:0)
ios6
locationManager:didUpdateToLocation:fromLocation:
中的,因此您需要在代码中添加其他方法...
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// this method get called in ios7 .
}
答案 4 :(得分:0)
在iOS -8中需要做一些更改: