This is probably more of an objective-c question over iOS but I've seen some example code similar to the following that I'd like to better understand.
@interface MyMapView : MKMapView <MKMapViewDelegate> {
// ivars specific to derived class
}
@property(nonatomic,assign) id<MKMapViewDelegate> delegate;
@end
@implementation MyMapView
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// initialize the ivars specific to this class
// Q1: Why invoke super on this delegate that's also a property of this class?
super.delegate = self;
zoomLevel = self.visibleMapRect.size.width * self.visibleMapRect.size.height;
}
return self;
}
#pragma mark - MKMapViewDelegate methods
// Q2: Why intercept these callbacks, only to invoke the delegate?
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
if( [delegate respondsToSelector:@selector(mapView:regionWillChangeAnimated:)] )
{
[delegate mapView:mapView regionWillChangeAnimated:animated];
}
}
@end
My two questions are: 1. Why would one invoke the super.delegate and also only declare the 'delegate' as a property? 2. Why intercept all of the dele开发者_Go百科gate calls only to forward them back to the delegate?
I appreciate any insights.
Apple's documentation explicitly states that you should avoid subclass MKMapView
:
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/doc/uid/TP40008205
Although you should not subclass the MKMapView class itself, you can get information about the map view’s behavior by providing a delegate object.
So i guess this delegate "forward" pattern is used to not break things.
I use a little different approach to subclass MKMapView
. To minimize breakage i use two classes. One that subclass MKMapView
and just override the init/dealloc method and assign/release the delegate
property to a instance of the other class. The other class is a subclass of NSObject
that implements the MKMapViewDelegate
protocol and will be the one that does the real work.
MyMapView.h
@interface MyMapView : MKMapView
@end
MyMapView.m
// private map delegate class
@interface MapDelegate : NSObject <MKMapViewDelegate>
// instance is not alive longer then MKMapView so use assign to also solve
// problem with circular retain
@property(nonatomic, assign) MKMapView *mapView;
@end
@implementation MapDelegate
@synthesize mapView;
- (id)initWithMapView:(ReportsMapView *)aMapView {
self = [super init];
if (self == nil) {
return nil;
}
self.mapView = aMapView;
return self;
}
// MKMapViewDelegate methods and other stuff goes here
@end
@implementation MyMapView
- (id)init {
self = [super init];
if (self == nil) {
return nil;
}
// delegate is a assign property
self.delegate = [[MapDelegate alloc] initWithMapView:self];
return self;
}
- (void)dealloc {
((MapDelegate *)self.delegate).mapView = nil;
[self.delegate release];
self.delegate = nil;
[super dealloc];
}
@end
The mapView
property for MapDelegate
class is not strictly needed but is probably useful if want to do things to the map view that that is not a result of some MKMapViewDelegate
method call, timers etc.
Why would one invoke the super.delegate and also only declare the 'delegate' as a property? Ans. As you are making a custom mapview it is important to call the delegates too.We are invoking the super class delegate to send control from the custom Mapview.
Why intercept all of the delegate calls only to forward them back to the delegate? Ans.At that line of code we are sending back the control to that delegate method declared in super class to do some useful thing.
Hope it will solve the query.
精彩评论