Reputation: 538
I'm trying to use a static class, MyClass
, as a delegate for its own static CLLocationManager
member, but the CLLocationManager
delegate methods I've implemented aren't being called. I've set the delegate as [myClass class]
, properly implemented the delegate methods, and included the protocol in MyClass.h.
@interface iOSSonic : NSObject <CLLocationManagerDelegate>
locationManager declaration:
@implementation myClasss : NSObject
...
static CLLocationManager *locationManager = nil;
I'm lazily instantiating the static CLLocationManager via the follow method:
+(CLLocationManager*)getLocationManager {
if (locationManager == nil) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = [myClass class]; // we set the delegate of locationManager to self.
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // setting the accuracy
locationManager.distanceFilter = 0.5; // get updates for location changes > 0.5 m
[locationManager requestWhenInUseAuthorization];
}
return locationManager;
}
...and then from my ViewController calling the following MyClass method:
+(void)myFunction {
[self.getLocationManager startUpdatingLocation];
}
Delegate method implementations:
...
+(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
...
}
+(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
...
}
// no initialization needed for static myClass
- (IBAction)onButtonClick:(id)sender {
[myClass myFunc] // This should trigger the didUpdateLocations delegate method, but it doesn't
To ensure that this wasn't some problem related to having the delegate be a static (non-instantiable) class and the delegate callbacks be class methods, I also tried with locationManager as a @property rather than a static member, and created an instance of myClass, setting myClass's locationManager's delegate to self. I also replaced getLocationManager
with an overridden locationManager getter, and changed the delegate callbacks to instance methods.
Initialization:
-(id)init {
if (self = [super init]) {
// do nothing
}
return self;
}
LocationManager declaration and instantiation:
...
@interface MyClass()
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
@implementation
...
// Lazily instantiate locationManager
-(CLLocationManager*)locationManager {
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self; // we set the delegate of locationManager to self.
_locationManager.desiredAccuracy = kCLLocationAccuracyBest; // setting the accuracy
_locationManager.distanceFilter = 0.5; // get updates for location changes > 0.5 m
[_locationManager requestWhenInUseAuthorization];
}
return _locationManager;
}
Delegate method implementations:
...
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
...
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
...
}
...
@property (strong, nonatomic) myClass *myClassInstance;
...
- (void)viewDidLoad
{
[super viewDidLoad];
...
self.myClassInstance = [[myClass alloc] init];
What am I doing wrong?
Upvotes: 0
Views: 1022
Reputation: 538
It was a stupid location services permissions thing. Turns out it had nothing to do with static members, classes vs. instances, etc. This fixed it for me: https://stackoverflow.com/a/25765345/1402368
Of course it was something stupid like this...
Upvotes: 0
Reputation: 131418
Here's my understanding of what's going on:
Instance method calls and class method calls are semantically different in Objective-C, and not interchangeable.
The method declarations:
+(void)someMethod;
and
-(void)someMethod;
Define 2 different kinds of methods. To call them, you have to know if you're calling an instance method or a class method, and code accordingly.
The location manager is written to call INSTANCE methods on it's delegate, not class methods.
Thus, you can't do what you're trying to do (make a CLASS a delegate instead of an instance of a class.)
You might be able to design your own custom class who's objects expect to have a class set as their delegate, but then you would only ever be able to assign a class as the delegate, never an instance of that class.
Upvotes: -1