MKMapViewDelegate派生类和委托赋值

时间:2011-09-28 17:10:42

标签: iphone objective-c ios

这可能是关于iOS的一个客观问题,但我已经看到了一些与以下类似的示例代码,我想更好地理解。

@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

我的两个问题是: 1.为什么要调用super.delegate并且只将'delegate'声明为属性? 2.为什么拦截所有委托调用只是将它们转发回委托?

我很感激任何见解。

2 个答案:

答案 0 :(得分:2)

Apple的文档明确声明您应该避免使用子类MKMapView

http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/doc/uid/TP40008205

  

虽然您不应该将MKMapView类本身子类化,但您可以   通过提供委托获取有关地图视图行为的信息   对象

所以我猜这个委托“前进”模式用于不破坏事物。

我对子类MKMapView采用了一种不同的方法。为了减少破损,我使用两个类。一个子类MKMapView,只是覆盖init / dealloc方法,并将delegate属性分配/释放到另一个类的实例。另一个类是NSObject的子类,它实现了MKMapViewDelegate协议,并且将是完成实际工作的协议。

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

mapView类的MapDelegate属性不是严格需要的,但如果想要对地图视图执行某些MKMapViewDelegate方法调用的结果,则可能很有用,计时器等。

答案 1 :(得分:1)

  1. 为什么要调用super.delegate并且只将'delegate'声明为属性? 答。在制作自定义mapview时,调用委托也很重要。我们正在调用超类委托从自定义Mapview发送控件。

  2. 为什么拦截所有委托调用只会将它们转发回委托? Ans.At那段代码我们将控件发送回超类中声明的委托方法来做一些有用的事情。

  3. 希望它能解决问题。