2011-02-09 2 views
9

Я создаю приложение на основе MapKit для iPhone.Можно ли наследовать от MKPolyline

У меня есть количество MKPolylines, добавленных к карте.

Однако, вместо того, чтобы иметь MKPolyline, я хотел бы, чтобы мой класс Model соответствовал протоколу MKOverlay, добавленному на карту, чтобы я мог получить доступ к свойствам модели при создании соответствующего представления в mapView: viewForOverlay.

Проблема в том, что я не могу найти способ наследования от MKPolyline, потому что у него нет никаких методов init, которые я могу вызвать из подзаклада init. Вы можете создавать их только с помощью удобных методов.

Как я могу объединить свойства модели и поведение MKPolyline?

ответ

4

Вы можете set an associated object attribute класса. Это позволяет привязать переменную экземпляра к существующему классу. Удостоверьтесь, что вы правильно очищаете себя.

2

Верно, что MKPolyline не имеет собственного метода инициализации. На самом деле единственным классом в цепочке наследования MKPolyline, который имеет метод init, является NSObject.

Так что, когда я подклассы MKPolyline Я просто перегрузили метод инициализации, определенный NSObject ...

-(id) init { 
    self = [super init]; 
    if(self) { 
     //my initialization here 
    } 
    return self; 
} 

Затем, когда вы хотите создать экземпляр подкласса с координатами вы могли бы сделать что-то вроде этого ...

-MyPolyline* myPolyline = (MyPolyline*)[MyPolyline polylineWithCoordinates:coordinates count:coordinateCount]; 
+0

Проблема с этим состоит в том, что тогда нет способа установить координаты, так как координаты являются свойствами readonly и могут быть установлены только методом удобства. Я тоже надеялся подклассировать MKPolyline, просто добавить в него часть информации, но, похоже, я не могу этого сделать. – GendoIkari

+0

Существует способ установить координаты в подклассе MKPolyline, вот фрагмент кода ... MyPolyline * myPolyline = (MyPolyline *) [MyPolyline polylineWithCoordinates: count count: coordCount]; –

+3

polylineWithCoordinates всегда возвращает MKPolyline ... он никогда не вернет MyPolyline. Таким образом, даже если вы делаете это так, все, что вы делаете, говорит компилятору, что это MyPolyline. В памяти это все равно будет MKPolyline. – GendoIkari

2

UPDATE: есть еще один вариант (может быть, лучше) использовать пересылку сообщения для этого (например, -forwardingTargetForSelector или прочее).

У меня была такая же проблема сегодня, но придумал другое решение. Вместо того, чтобы использовать предложенные Wayne связанные объекты атрибутов объекта, я просто инкапсулировал MKPolyline в другой класс и передал ему сообщения протокола MKOverlay.

Так что у меня есть кое-что, как и в .h:

@interface MyOverlay : NSObject <MKOverlay> 
{ 
    MKPolyline* polyline; 
    id object; 
} 

@property (nonatomic, retain) id object; 
@property (nonatomic, retain) MKPolyline* polyline; 

+ (MyOverlay*)myOverlayWithObject: (id)anObject; 

@end 

И в .m:

@implementation MyOverlay 
@synthesize object; 
@synthesize polyline; 


+ (MyOverlay*)routePartOverlayWithObject: (id)anObject {  

    MyOverlay* myOverlay = [[MyOverlay alloc] init]; 

    ... generating MKPolyline ... 

    myOverlay.polyline = ... generated polyline ...; 
    routePartOverlay.object = anObject; 


    return [myOverlay autorelease]; 
} 

- (void) dealloc { 
    [cdRoutePart release]; cdRoutePart = nil; 
    [polyline release]; polyline = nil; 

    [super dealloc]; 
} 

#pragma mark MKOverlay 
//@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; 
- (CLLocationCoordinate2D) coordinate { 
    return [polyline coordinate]; 
} 

//@property (nonatomic, readonly) MKMapRect boundingMapRect; 
- (MKMapRect) boundingMapRect { 
    return [polyline boundingMapRect]; 
} 

- (BOOL)intersectsMapRect:(MKMapRect)mapRect { 
    return [polyline intersectsMapRect:mapRect]; 
} 

@end 

MyOverlay Так ведет себя как MKPolyline (соответствует MKOverlay) и в то же время я может делать с ним все, имея столько свойств, сколько мне нужно.

+0

Не мог ли человек с downvote объяснить, что случилось с этим ответом? –

7

код MANIAK_dobrii является путем, но я нашел, что я должен был реализовать некоторые дополнительные методы MKMultiPoint, чтобы заставить его работать, вот мои полные заголовки и реализация файлы для AnchorLine класса я использовал: -

Заголовок AnchorLine .h

#import <MapKit/MapKit.h> 

@interface AnchorLine : NSObject <MKOverlay> { 
    MKPolyline* polyline; 
} 

@property (nonatomic, retain) MKPolyline* polyline; 

+ (AnchorLine*)initWithPolyline: (MKPolyline*) line; 
@end 

AnchorLine.m Реализация

#import "AnchorLine.h" 

@implementation AnchorLine 

@synthesize polyline; 


+ (AnchorLine*)initWithPolyline: (MKPolyline*) line { 
    AnchorLine* anchorLine = [[AnchorLine alloc] init]; 
    anchorLine.polyline = line; 
    return [anchorLine autorelease]; 
} 

- (void) dealloc { 
    [polyline release]; 
    polyline = nil; 
    [super dealloc]; 
} 

#pragma mark MKOverlay 
//@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; 
- (CLLocationCoordinate2D) coordinate { 
    return [polyline coordinate]; 
} 

//@property (nonatomic, readonly) MKMapRect boundingMapRect; 
- (MKMapRect) boundingMapRect { 
    return [polyline boundingMapRect]; 
} 

- (BOOL)intersectsMapRect:(MKMapRect)mapRect { 
    return [polyline intersectsMapRect:mapRect]; 
} 

- (MKMapPoint *) points { 
    return [polyline points]; 
} 


-(NSUInteger) pointCount { 
    return [polyline pointCount]; 
} 

- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range { 
    return [polyline getCoordinates:coords range:range]; 
} 

@end 

Надеется, что кто-то помогает.

0

Описанные здесь до сих пор не совсем сработали для меня, но мне удалось найти решение, основанное на других ответах и ​​некоторых независимых исследованиях. Я не на 100% уверен в этом, но вы можете использовать MKPolyline в пользовательский подкласс только, если вы используете вызов статического метода, который внутренне вызывает правильный метод init.

(CustomPolyline*)[CustomPolyline polylineWithCoordinates:coordinates count:coordinateCount] 

выше не будет работать, так как polylineWithCoordinates только выделяет память для MKPolyline объекта, а не CustomPolyline. Я подозреваю, что происходит внутри, так это то, что polylineWithCoordinates вызывает другой метод инициализации способом, похожим на: [MKPolyline otherInitMethod:...]. И он не выделяет надлежащий объем памяти, потому что теперь он использует статический вызов MKPolyline, а не статический вызов CustomPolyline.

Однако, если мы используем

(CustomPolyline*)[CustomPolyline polylineWithPoints:polyline.points count:polyline.pointCount]; 

Это делает работу. Я думаю, это потому, что polylineWithPoints использует инициализатор, который возвращает id, а не просто привязку к другому вызову метода. И так как мы назвали его с помощью класса CustomPolyline, инициализатор выделяет память для CustomPolyline не MKPolyline.

Возможно, я ошибаюсь, почему он работает. Но я тестировал это, и, похоже, он работает нормально. MKPolygon может быть продлен аналогичным образом. В этом случае я думаю, что правильный статический метод, чтобы использовать это MKPolygon polygonWithCoordinates:points count:pointSet.count]]

Моя реализация для справки:

CustomPolyline.h

#import <MapKit/MapKit.h> 

typedef enum { 
    CustomPolylineTypeNone = 0, 
    CustomPolylineDifferentStrokes 
} CustomPolylineType; 

/** 
* CustomPolyline wraps MKPolyline with additional information about a polyline useful for differentiation. 
*/ 
@interface CustomPolyline : MKPolyline 

@property CustomPolylineType type; 

-(CustomPolyline*)initWithMKPolyline:(MKPolyline*)polyline; 

@end 

CustomPolyline.m

#import "CustomPolyline.h" 

@implementation CustomPolyline 

@synthesize type; 

/** 
* Takes an MKPolyline and uses its attributes to create a new CustomPolyline 
*/ 
-(CustomPolyline*)initWithMKPolyline:(MKPolyline*)polyline 
{ 
    // We must use the this specific class function in this manner to generate an actual 
    // CustomPolyline object as opposed to a MKPolyline by a different name 
    return (CustomPolyline*)[CustomPolyline polylineWithPoints:polyline.points count:polyline.pointCount]; 
} 

@end 
Смежные вопросы