开发者

Question about delegation in Objective-C, CLLocationManager

I'm getting a bit confused how delegation works. I believe the idea is to have another class do the work for you and call you back. So if you did something like this:

- (void)viewDidLoad {
    [super viewDidLoad];
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    if (CLLocationManager.locationServicesEnabled == YES) {
        NSLog(@"location enabled");
        latitudeLabel.text = [NSString stringWithFormat:@""];
        [locationManager startUpdatingLocation];
    }
    NSLog(@"%g", locationCoordinate.latitude);
}

If I NSLog the coordinate in the viewDidLoad, even though I startUpdatingLocation, the value of my locationCoordinate property is 0. But if I NSLog the value in the delegate method like so:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    NSString *latitudeString = [[NSString alloc] initWithFormat: @"%g m", newLocation.coordinate.latitude];
    latitudeLabel.text = latitudeString;
    [latitudeString release];
    locationCoordinate = newLocation.coordinate;
    NSLog(@"in delegate: %g", locationCoordinate.latitude);
}

I get an actual location value. I thought that by using the delegate method, my locationProper开发者_JS百科ty would get set, but it seems not to. Am I understanding delegation incorrectly? Thanks.


A major reason why delegates exist is in fact in situations like the one you describe.

You have some functionality in a class, but the functionality is asynchronous, i.e. you can't just go get the info right off the bat, or it's implemented asynchronously (for example, downloading a huge file off the net should/does happen asynchronously, to not lock up the whole interface for a minute+).

So using delegation you can say "just become my delegate and I'll eventually get back to you, we're done for now". The object can then return back to the caller at its convenience, rather than the opposite (being called only when the main application wants it).

As said, downloading files and such is exactly where delegation comes into play. It's also a very useful tool for your own coding to incorporate delegates in your code, in cases where you either have to wait on delegation from some other object (such as CLLocationManager), or you have to process something on a separate thread (such as parsing data or whatnot).


The only thing the delegation gets you is that the locationManager calls your delegate method(s). Objects usually do not change their delegate's properties.

So to be sure that your coordinate property is updated, you'd have to implement the CLLocationManager's delegate method the way you did. Actually I'd suggest you don't use the locationCoordinate property at all and instead use the LocationManager's location property.


After you enable location services it takes a time until the values for location are there. That's probably why you don't get results in you first example. ( that and I think you must call the startUpdatingLocation method ).
The idea with the delegate here is that the class that you set as a delegate more or less promises to implement methods that the caller can then call whenever HE thinks it's necessary.

As the method signature in your second example implies, the Locationmanager is the one who knows about updates happening, and the delegate enables him then to take action. If you would not use something like that, you would have to query for changes in location periodically


To understand what is going on here you should first try to understand the delegation pattern. It is an object oriented pattern that applies to many languauges:

http://en.wikipedia.org/wiki/Delegation_pattern

In this case CLLocationManager performs the task of finding the location. When it is done with this task it knows that you probably want to do something with the information it gathered but it doesn't really know what. By setting "self" as the delegate you are telling CLLocationManager that when it's done getting the location you will take care of what happens next. You do that by implementing the locationManager delegate method. When the location manager is done finding the location it will call that method, but not before then. In your first NSSLog you are looking at the latitude before the location manager has figured out what the current latitude it is.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜