簡體   English   中英

使用類(不是實例)作為iOS委托,不會調用CLLocationManager委托回調

[英]Using a class (not an instance) as an iOS delegate, CLLocationManager delegate callbacks aren't called

相關: 我可以使用類方法作為委托回調嗎?

我正在嘗試使用靜態類MyClass作為其自己的靜態CLLocationManager成員的委托,但未調用我已實現的CLLocationManager委托方法。 我將委托設置為[myClass class] ,正確實現了委托方法,並將協議包含在MyClass.h中。

MyClass.h

@interface iOSSonic : NSObject <CLLocationManagerDelegate>

MyClass.m

locationManager聲明:

@implementation myClasss : NSObject
...
static CLLocationManager *locationManager = nil;

我通過以下方法延遲實例化靜態CLLocationManager:

+(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;
}

...然后從我的ViewController調用以下MyClass方法:

+(void)myFunction {
    [self.getLocationManager startUpdatingLocation];
}

委托方法實現:

...
+(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
...
}

+(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
...

}

ViewController.m

// no initialization needed for static myClass

- (IBAction)onButtonClick:(id)sender {
    [myClass myFunc] // This should trigger the didUpdateLocations delegate method, but it doesn't 

為了確保這與將委托設為靜態(不可實例化)類並將委托回調設為類方法無關,我還嘗試使用locationManager作為@property而非靜態成員,並創建了一個實例myClass,將myClass的locationManager的委托設置為self。 我還用覆蓋的locationManager getter替換了getLocationManager ,並將委托回調更改為實例方法。

MyClass.m

初始化:

-(id)init {
    if (self = [super init]) {
        // do nothing
    }
    return self;
}

LocationManager的聲明和實例化:

...
@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;
}

委托方法實現:

...
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
...
}

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

}

ViewContoller.h

...
@property (strong, nonatomic) myClass *myClassInstance;
...

ViewController.m

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        ...
        self.myClassInstance = [[myClass alloc] init];

我究竟做錯了什么?

這是愚蠢的位置服務權限。 事實證明,它與靜態成員,類與實例等無關。這為我解決了這一問題: https : //stackoverflow.com/a/25765345/1402368

當然,這有點愚蠢……

這是我對正在發生的事情的理解:

實例方法調用和類方法調用在Objective-C中在語義上有所不同,並且不能互換。

方法聲明:

+(void)someMethod;

-(void)someMethod;

定義2種不同的方法。 要調用它們,您必須知道要調用實例方法還是類方法,並相應地進行編碼。

位置管理器被編寫為在其委托上調用INSTANCE方法,而不是類方法。

因此,您無法做您想做的事情(使CLASS成為委托而不是類的實例)。

您可能可以設計自己的自定義類,這些對象的對象希望將一個類設置為其委托,但是您將永遠只能將一個類分配為委托,而永遠不能分配該類的實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM