14 Stimmen

Warum wird der CLLocationManager-Delegat nicht in iPhone SDK 4.0 aufgerufen?

Dies ist der Code, den ich in meiner AppDelegate-Klasse habe

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

Und dies ist die Delegate-Methode, die ich in meiner AppDelegate-Klasse habe

    //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);

}

Es funktioniert in 3.0, 3.1, 3.1.3, aber es funktioniert nicht in 4.0 Simulator und Gerät beide.

Was ist der Grund dafür?

21voto

SebastianView Punkte 834

Ich hatte einen ähnlichen Fehler, und ist jetzt gelöst. Das Problem ist, dass die Variable locationManager lokal deklariert wird. Deklarieren Sie sie stattdessen als Klassenvariable und stellen Sie sicher, dass sie entweder direkt oder über die Eigenschaft retain (oder strong, wenn Sie ARC verwenden) beibehalten wird. Damit ist das Problem gelöst! Das Problem war, dass die locationManager-Variable freigegeben wurde und den Delegaten nie aktualisiert hat. Hier der Code:

.h-Datei:

#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-Datei:

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

Ich hoffe, es hilft.

4voto

Smartcat Punkte 2717

Ich wurde verrückt, als ich versuchte herauszufinden, warum nur eine von mehreren Klassen, die einen CLLocationManager verwenden, nie einen Aufruf an tout der CLLocationManagerDelegate-Methoden.

Es stellt sich heraus: diese Klasse wurde von einem Nicht-Haupt-Thread initialisiert, so dass seine CLLocationManager auf einem Nicht-Haupt-Thread erstellt wurde... es könnte sogar ein temporärer Thread gewesen sein. Wie auch immer, Wrapping den Aufruf zu initialisieren meine Klasse mit der unten war alles, was es brauchte, um meine CLLocationManager delegieren Methoden aufgerufen werden.

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

Also unterm Strich: Erstellen Sie keinen CLLocationManager auf einem anderen als dem Hauptthread, sonst werden Ihre Delegatenmethoden nie aufgerufen! Ich wusste das mal... ist nur schon lange her... seufz. Habe einen Tag verschwendet, um das wieder herauszufinden! Da alle CLLocationManager SO's, die ich gelesen habe, dies nie erwähnt haben, poste ich es hier. Hoffentlich hilft es jemandem!

2voto

Thomas Müller Punkte 15400

Hat -locationManager:didFailWithError: Wurde Ihr Delegierter jemals angerufen? Ich denke nur, dass Sie vielleicht irgendwann den Zugriff auf Standortdaten verweigert haben und jetzt nicht aufgefordert werden, aber der Zugriff verweigert wird.

0voto

Sind Sie sicher, dass Sie den Standortmanager nicht irgendwo deallokieren? Der Code, den Sie haben, zeigt, dass es in der didFinishLaunching... Methode zugewiesen wird, aber dann vergessen wird (obwohl es noch beibehalten wird und so sollte noch funktionieren).

Sehen Sie überhaupt das anfängliche Popup-Fenster, in dem Sie gefragt werden, ob es OK ist, den Standort des Benutzers zu ermitteln?

0voto

Howard Punkte 35

Fügen Sie die Codes in einen viewController ein, der zum navigationController geschoben wird".

Mein Code lautet.

In SomeViewController.h

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

In 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];
}

Das Problem, das ich denke, ist, weil der ARC, locationManager freigegeben ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X