2011-09-28 61 views
2

这可能更多的是iOS上的objective-c问题,但我已经看到了一些类似于下面的代码,我想更好地理解它。MKMapViewDelegate派生类和委托分配

@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,也只有宣布“代理”的财产? 2.为什么只拦截所有的委托来电转回委托?

我很欣赏任何见解。

回答

2

苹果的文件明确规定,你应该避免子类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. 为什么要调用super.delegate并且只声明'delegate'作为属性? Ans。由于您正在制作自定义的mapview,因此调用委托也很重要。我们正在调用超级委托来从自定义Mapview发送控件。

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

希望它能解决查询。