delegation

A delegate is an object referenced using Objective-C’s anonymous type, id.

Delegate messages usually include one of three verbs: should, will, or did.

You could try polling the location manager to get the location, but the amount of time it takes to determine the current location is too variable for polling to be efficient.

The best solution is for the location manager to take matters into its own hands. Whenever it finds the current location, it sends the message locationManager:didUpdateToLocation:fromLocation:. Who is sent the message? The location manager's delegate.

Every CLLocationManager has a delegate property, and we can set this property to point to the object that should receive the "location found" message.

WhereamiAppDelegate.m

- (BOOL)              application: (UIApplication *) application
    didFinishLaunchingWithOptions:(NSDictionary *) launchOptions
{
    locationManager = [[CLLocationManager alloc]init];

    [locationManager setDelegate:self];

    ...
}

- (void) locationManager:(CLLocationManager *) manager
     didUpdateToLocation:(CLLocation *)newLocation
            fromLocation:(CLLocation *) oldLocation
{
    NSLog(@"%@",newLocation);
}

- (void) locationManager:(CLLocationManager *) manager
             didFailWithError:(NSError *)error
{
    NSLog(@"Could not find location: %@", error);
}

When you set the delegate property of the CLLocationManager and implemented the two methods in WhereamiAppDelegate, you were using a design pattern called delegation. This is a very common pattern in Cocoa Touch, and many classes have a delegate property.

Delegation is an object-oriented approach to callbacks. A callback is a function that is supplied in advance of an event and is called everytime the event occurs.

However, there is no built-in way for two callback functions to coordinate and share information. This is the problem addressed by delegation - we supply a single delegate to receive all of the event messages for a particular object. This delegate object can then store,manipulate,act on, and relay the related information as it sees fit.

Target-action vs delegation

let's take a moment to compare delegation with another object-oriented approach to callbacks: target-action pairs.

In a target-action pair, you have a target object that you send an action message to when an event occurs.

The target must implement the action message, and, for each event, a new target-action pair must be created. With delegation, on the other hand, you set the delegate once and can then send it messages for different events, The delegate will implement the method for each event it wants to hear about.

Also, with a target-action pair, you can send the target any action message you choose. Delegation, however, does not offer this flexibility; an object can only send its delegate a specific set of messages listed in a protocol.

 

Before sending an optional method, the object first asks its delegate by sending another message, respondsToSelector:. Every object implements this method, which checks at runtime whether an object implements a given method. You can turn a selector into a value you can pass as an argument with the @selector() directive. For Example, CLLocationManager could implement a method looks like this,

- (void) finishedFinishingLocation:(CLLocation *) newLocation
{
    SEL updateMethod = @selector(locationManager:didUpdateToLocation:fromLocation:);

    if([[self delegate] respondsToSelector:updateMethod]){
    //if the method is implemented, then we send the message
    [[self delegate] locationMagager:self
                 didUpdateToLocation:newLocation
                        fromLocation:oldLocation];
}

 To avoid retain cycle, delegate properties use the assign attribute instead of retain of copy. We call this a "weak reference" , where an object has a pointer to another object but does not retain it.

@property (nonatomic, assign) id delegate;
//or 
@property (nonatomic,weak) id delegate;

dealloc

- (void) dealloc
{
    if([locationManager delegate] == self){
        [locationManager setDelegate:nil;
    }
    [locationManager release];
    [window release];
    [super dealloc];
}

 

posted on 2012-06-13 15:07  grep  阅读(509)  评论(0编辑  收藏  举报