#iphone #objective-c #ios
#iPhone #objective-c #iOS
Вопрос:
Вероятно, это скорее вопрос objective-c по сравнению с 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, а также объявлять только «делегат» как свойство?
2. Зачем перехватывать все вызовы делегата только для того, чтобы переслать их обратно делегату?
Я ценю любую информацию.
Ответ №1:
В документации Apple явно указано, что вам следует избегать подкласса MKMapView
:
Хотя вам не следует создавать подкласс самого класса 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
-либо вызова метода, таймеров и т. Д.
Ответ №2:
-
Зачем вызывать super.delegate, а также объявлять только «делегат» как свойство? Ans. Поскольку вы создаете пользовательский mapview, важно также вызывать делегатов.Мы вызываем делегат суперкласса для отправки управления из пользовательского Mapview.
-
Зачем перехватывать все вызовы делегата только для того, чтобы переслать их обратно делегату? Ans.В этой строке кода мы отправляем обратно элемент управления этому методу делегирования, объявленному в суперклассе, чтобы сделать что-то полезное.
Надеюсь, это решит запрос.