Reputation: 26223
I am a little confused about setting up the MKReverseGeocoderDelegate, I noted from Apples example that they are assigning the MKReverseGeocoder to a property iVar, in the end I decided to alloc the MKReverseGeocoder when a position is found and release the MKReverseGeocoders as they either report back success or failure, does this seem right?
// ------------------------------------------------------------------- **
// DELEGATE: CLLocationManager
// ------------------------------------------------------------------- **
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
MKReverseGeocoder *myGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]];
[myGeocoder setDelegate:self];
[myGeocoder start];
}
// ------------------------------------------------------------------- **
// DELEGATE: MKReverseGeocoderDelegate
// ------------------------------------------------------------------- **
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
NSLog(@"%@", [placemark locality]);
[geocoder release];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
[geocoder release];
}
@end
Upvotes: 0
Views: 1257
Reputation: 21903
You're fine in terms of memory management. If you run this through the leaks tool in Instruments, it'll probably complain about a possible leak in your locationManager:didUpdate
method, but it's wrong about that, it just can't see where you're releasing the object.
I would do a couple things to decrease the impact on the geocoder, though. I'd look and see that the location you just didUpdate
to has an accuracy that's worth talking about. When Core Location first comes to life, you're likely to get some garbage hits before the hardware's really up and receiving. And then the accuracy will narrow in on the real location (the Google Maps app shows pretty nicely what is happening there, the blue circle zeroing in on your real location). There's probably no point in geocoding until you've got an accuracy within 100 meters or so.
EDIT: Try this
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
if((newLocation.coordinate.latitude != oldLocation.coordinate.latitude) &&
(newLocation.coordinate.longitude != oldLocation.coordinate.longitude) &&
([newLocation horizontalAccuracy] < 100 && [newLocation horizontalAccuracy] > 0))
{
MKReverseGeocoder *myGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]];
[myGeocoder setDelegate:self];
[myGeocoder start];
}
}
That should ignore updates that are the same as the last update (which might be fairly frequent) and those that have invalid accuracy (you'll get negative numbers there occasionally, when the location hardware is first fired up) or are over 100 meters of horizontal accuracy.
Also, if you just want to do this once, go ahead and have your CLLocationManager stop updating once you get a valid and sufficiently accurate position.
Upvotes: 3
Reputation: 10009
In the MKReverseGeocoder Class Reference, Apple says that
Each Map Kit application has a limited amount of reverse geocoding capacity, so it is to your advantage to use reverse geocode requests sparingly. Here are some rules of thumb for using this class most effectively:
- Send at most one reverse-geocoding request for any one user action.
(...)
In your case, If there is a slow network connection (i.e. position changes are faster then location lookups), multiple requests can be instantiated.
Your code will probably work fine in most cases, however it is not the suggested way to implement it. And implementing anything that only works "in most cases" is not a goot idea at all.
Upvotes: 1