2016-06-24 19 views
0

Ich habe mir in den letzten paar Tagen den Kopf gestoßen und es begann langsam mich zu entwässern. Ich versuche CLLocationManager Singleton zu erstellen, da ich einen Speicherort für zwei andere Komponenten meiner App benötige. Ich bekomme jedoch weiterhin EXC_BAD_ACCESS, wenn ich die Eigenschaft currentLocation setze. Wenn ich darüber hinaus komme, bekomme ich ein SIGABRT auf main.m Oh und um das Ganze abzurunden, wenn es vorbei ist, werde ich zusammen mit der SIGABRT darüber informiert, dass meine KVO-Nachricht eingegangen ist, aber nicht bearbeitet wird und ich keine Ahnung habe das bedeutet.Einstellungseigenschaft Ursachen EXC_BAD_ACCESS Absturz (CLLocationManager Singleton)

Jede Hilfe ist zusammen mit Ressourcen auf KVO und/oder Ressourcen zu den Wurzeln schätzte ich vor der Verwendung KVO

LocationFetch.h

@interface LocationFetch : NSObject <CLLocationManagerDelegate> 

+(LocationFetch *) sharedInstance; 

@property (nonatomic,strong) CLLocationManager *locationManager; 
@property (nonatomic, strong) CLLocation *currentLocation; 

-(void)startingUpdatingLocation; 
-(void)stopUpdatingLocation; 

@end 

LocationFetch.m

#import "LocationFetch.h" 

@implementation LocationFetch 

@synthesize locationManager, currentLocation; 

+(LocationFetch *) sharedInstance 
{ 
    static LocationFetch *instance; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     instance = [[self alloc]init]; 
     }); 
    return instance; 
} 
- (id)init 
{ 
    self = [super init]; 
    if(self) 
    { 

     self.locationManager = [[CLLocationManager alloc]init]; 
     self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
     self.locationManager.distanceFilter = 100; 
     self.locationManager.delegate = self; 
     //Request Authorization 
     if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) 
     { 
      [self.locationManager requestWhenInUseAuthorization]; 
     } 
    } 
    return self; 
} 
- (void)startingUpdatingLocation 
{ 
    [self.locationManager startUpdatingLocation]; 
    NSLog(@"Starting Location Updates"); 
} 
-(void)stopUpdatingLocation 
{ 
    [self.locationManager stopUpdatingLocation]; 
    NSLog(@"Stopping Location Updates"); 
} 
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{ 
    NSLog(@"Location updates failed with %@", error); 
} 
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations 
{ 
    CLLocation *location = [locations lastObject]; 
    NSLog(@"LocationFetch sharedInstance: Latitude %+.6f, Longitude %+.6f\n", 
      location.coordinate.latitude, 
      location.coordinate.longitude); 
    self.currentLocation = location; 
} 



@end 

Teil wissen sollten of WeatherFetch.m (hier wird der Beobachter registriert)

-(id)init 
{ 
    self = [super init]; 
    if(self) 
    { 
     [[LocationFetch sharedInstance] addObserver:self forKeyPath:@"currentLocation" options:NSKeyValueObservingOptionNew context:nil]; 
    } 
    return self; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 

change:(NSDictionary *)change context:(void *)context 
{ 
    if([keyPath isEqualToString:@"currentLocation"]) { 
     [self setWeatherLocation]; 
     [self sendWeatherRequest]; 
     NSLog(@"Observer has received message"); 
     [self removeObserver:self forKeyPath:@"currentLocation" context:nil]; 
    } 
} 

EDIT: Dies war die Anleitung, die ich für die Singleton folgte: http://derpturkey.com/cllocationmanager-singleton/

Ein weiterer EDIT: Okay, ich habe über die EXC_BAD_ACCESS Fehler durch die Eigenschaft Attribute von starken und nonatomic für CLLocationManager und CLLocation entfernen, aber jetzt die SIGABRT ist jetzt ein kritischeres Problem, hier ist die Debug-Ausgabe von der Ausnahme. Auf der hellen Seite, erscheint KVO jetzt notifitied werden, nicht nur den Fehler verstehen „Nachricht empfangen wurde, aber nicht behandelt“

2016-06-24 21:25:51.111 TrafficAlarmClock[1504:18554] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '(
    "<CALayer: 0x7f95a043eb00>" 
): An -observeValueForKeyPath:ofObject:change:context: message was received but not handled. 
Key path: currentLocation 
Observed object: <LocationFetch: 0x7f95a040c5a0> 
Change: { 
    kind = 1; 
    new = "<+40.75921100,-73.98463800> +/- 5.00m (speed -1.00 mps/course -1.00) @ 6/24/16, 9:25:50 PM Eastern Daylight Time"; 
} 
Context: 0x1050f7c08' 
*** First throw call stack: 
(
    0 CoreFoundation      0x0000000105f97d85 __exceptionPreprocess + 165 
    1 libobjc.A.dylib      0x0000000105682deb objc_exception_throw + 48 
    2 CoreFoundation      0x0000000105f97cbd +[NSException raise:format:] + 205 
    3 Foundation       0x00000001052e71ae -[NSObject(NSKeyValueObserving) observeValueForKeyPath:ofObject:change:context:] + 168 
    4 Foundation       0x0000000105213cad NSKeyValueNotifyObserver + 347 
    5 Foundation       0x0000000105212f39 NSKeyValueDidChange + 466 
    6 Foundation       0x00000001052e7fff -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 912 
    7 Foundation       0x0000000105210804 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 60 
    8 Foundation       0x000000010526ea9b _NSSetObjectValueAndNotify + 261 
    9 TrafficAlarmClock     0x00000001050f2143 -[LocationFetch locationManager:didUpdateLocations:] + 227 
    10 CoreLocation      0x0000000105192418 CLClientGetCapabilities + 20974 
    11 CoreLocation      0x000000010518e823 CLClientGetCapabilities + 5625 
    12 CoreLocation      0x00000001051892dd CLClientInvalidate + 923 
    13 CoreFoundation      0x0000000105ebd2ec __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12 
    14 CoreFoundation      0x0000000105eb2f75 __CFRunLoopDoBlocks + 341 
    15 CoreFoundation      0x0000000105eb2d28 __CFRunLoopRun + 2472 
    16 CoreFoundation      0x0000000105eb20f8 CFRunLoopRunSpecific + 488 
    17 GraphicsServices     0x0000000108660ad2 GSEventRunModal + 161 
    18 UIKit        0x000000010634ef09 UIApplicationMain + 171 
    19 TrafficAlarmClock     0x00000001050f1b6f main + 111 
    20 libdyld.dylib      0x0000000108fd192d start + 1 
    21 ???         0x0000000000000001 0x0 + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 

Ein weiterer EDIT: Okay, ich glaube, ich wo ganz verstehen nicht, Dinge zu platzieren mag Beobachter und so in meine Bewerbung. Ich habe es jetzt so, dass mein Viewcontroller der Abonnent ist und ich jetzt näher an das Verhalten komme, das ich möchte. Wenn jemand gute Anleitungen zu MVC und Software-Design mit MVC/iOS-Entwicklung hat, bitte teilen. Buchempfehlungen sind ebenfalls willkommen.

+0

KVO ist wirklich eine gute Idee. Ich würde vorschlagen, dass Sie Ihr Singleton eine NSNotification veröffentlichen lassen und Ihre WeatherFetch das abonnieren lassen. Es kann dann den Wert aus dem Singleton – Paulw11

+0

abrufen Auch haben Sie nicht die '@ synthetisieren' Anweisungen für eine Reihe von Jahren benötigt – Paulw11

+0

Aus dem Lesen von Dutzenden von Ressourcen, sind sie nicht extrem ähnlich? – xinkecf35

Antwort

0

Kann nicht sagen, was verursacht die KVO Fehler, da es einen Mangel an Präzision ist aber nur zu sagen, was wir in einem ähnlichen Fall getan haben

dies ist, wie wir unsere Instanz LocationHelper zuteilen:

- (id)init { self = [super init]; 

if (!self) { 
    return self; 
} 

// Check if the service is available 
if ([CLLocationManager locationServicesEnabled]) 
{ 
    // Init the location manager 
    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 
    self.locationManager.pausesLocationUpdatesAutomatically = YES; 
    self.locationManager.desiredAccuracy = LOCATION_ACCURACY_IN_METER; 
} 

return self;} 

und dann verstehe ich nicht, warum Sie nicht verwenden:

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

und dann manager.location verwenden, um von hier setWeatherLocation oder sendWeatherRequest zu nennen.

Wenn es nicht das, was Sie erwarten, geben Sie bitte weitere Einzelheiten über den Absturz

+0

Dies war der Leitfaden, dem ich folgte http://derpturkey.com/cllocationmanager-singleton/. Der Fehler für KVO war, dass die Nachricht empfangen, aber nicht bearbeitet wurde – xinkecf35

0

Ich würde vorschlagen, anstelle eines Singletons schaffen nur eine Instanz auf App-Delegaten und der Benutzer speichern Koordinaten auf AppDelegate Auf diese Weise können Benutzer erhalten präzise Ort jederzeit können Sie müssen ihre Genauigkeit zu optimieren, so dass es nicht Batterie entladen und appdelegate ist bereits eine singletion :)

Wenn Sie mit singletion machen wollen Der Absturz mit KVO ist wegen dieser Linie :

[[LocationFetch sharedInstance] addObserver:self forKeyPath:@"currentLocation" options:NSKeyValueObservingOptionNew context:nil]; 

Wenn Sie einen Beobachter fügen Sie es selbst entfernen haben, versuchen Sie dies in der Singleton-Datei:

- (void)dealloc { 
[[LocationFetch sharedInstance] removeObserver:self forKeyPath:@"currentLocation"]; 
} 

Ich bin nicht 100% sicher Beobachter von einem Singleton class.The Code zum Entfernen scheint mir seltsam, aber Ich denke, es wird funktionieren