views:

212

answers:

3

I have an instance variable lat (NSString) in my App Delegate. What i want to do is set this variable equal to the user's current latitude in didUpdateToLocation:fromLocation, such that i can access it from a different view. This is key. So i have this code:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation {

    appDelegate = (myProjectAppDelegate *)[[UIApplication sharedApplication] delegate];

    appDelegate.lat = [[NSString alloc] initWithFormat:@"%g",newLocation.coordinate.latitude];
}

In terms of debugging, when i do po appDelegate.lat in the console, when a breakpoint is set here, then i can see the value fine. When i go to my ViewController where i want to use the value, i get out of scope when i hover over it, and cannot access memory at 0x0 when i try po appDelegate.lat. This is from the view controller:

    [appDelegate.locMan startUpdatingLocation];

    NSLog(@"here");
    NSLog(appDelegate.lat);

Since nothing is getting printed for my NSLog(appDelegate.lat) statement, i can only assume something is wrong.

What would be the correct way to debug this.

Thanks.

+1  A: 

Might need to see more code but it sounds like you may not be retaining appDelegate property of the viewController. Certainly the message cannot access memory at 0x0 means a null pointer.

If you can see the lat property in the application delegate but can't see it from the viewController then the problem is in the linkage between the appDelegate and the viewController. If you can see the .lat in one method of the viewController but not in another one, that suggest the appDelegate attribute of the viewController is not being properly retained.


Edit01:

Should add that you can set a breakpoint to log and continue on the

@synthesize lat;

line in the appDelegate source file. This will log every time one of the synthesized accessors/setters is called. This will tell you when the property is actually been accessed or set. You can a debugger function on the same breakpoint to print the value of lat as well.

If you need more info, you can write out explicit accessor/setter methods and put log statements inside them. I doubt you need to go that far in this case.

TechZen
Thanks. From what i can see, the lat is only synthesized once. I have used the appDelegate = [[...sharedApplication] notation in other classes before to set array objects, and then access them from the same view controller im using now, and can do that fine. So i thought using the same idea to set lat would work, as the object should be retained shouldnt it?
joec
A: 

Without more code, and some holiday-hangover lingering, it looks like you are getting a local copy of the app delegate and setting the lat ivar on it, and the local copy of the app delegate is destroyed (along with the lat ivar you set on it) on exit and thus you get the null pointer stuff when you try to later get the lat value.

I find making getter/setters on objects is best to pass data from one object to another in Cocoa-type apps.

Create a "setter" method on your app delegate that accepts the lat value, sets it internally to the app delegate object in a protected property, and finally make a separate "getter" method that simply returns the lat value from the app delegate. Or put the setter/getter methods on whatever object makes sense in your app.

The naming convention is usually: "setNAMEOFVAR" And "getNAMEOFVAR" for setters and getters respectively.

That should work for you.

ExitToShell
I think this is correct. Joec should use `self.appDelegate` everywhere to ensure it gets properly retained.
TechZen
I tried adding a protected property, and created setters and getters, but it still just returned a null pointer. Any other ways of passing these values through?
joec
A: 

The code above is actually correct. You're passing messages to the app delegate singleton and certainly don't want to retain a strong reference to it.

Without more code it's a little difficult to see the program flow but it looks like you're passing startUpdatingLocation to a LocationManager referenced from your app delegate subclass. I'd first check that the LocationManager's delegate is set to the class in which your second snippet is from - otherwise it will never be hit. However it looks like it is as you seem to be seeing an update in you NSLog statements.

Secondly I'd remember that the LocationManager will be updating asynchronously. Don't expect to receive an update immediately after you start updating location. Therefore it is quite reasonable to expect that the lat would be nil for some seconds after start update location.

Thirdly I'd be looking at the other controller (where you're trying to read the result). Are you in a breakpoint within the class when you're trying to get the app delegate?

BTW, your app architecture seems a little (pardon me) ugly. Is there a reason you need to so closely couple your app delegate and controllers? A more elegant way may be to create a your own location management singleton and have it post notifications. Any class that is interested may then subscribe to these location update notifications.

Grumpy Chuck