2011-02-09 37 views
9

Tôi đang xây dựng một ứng dụng dựa trên MapKit cho iPhone.Có thể kế thừa từ MKPolyline

Tôi có một số MKPolylines được thêm vào bản đồ.

Tuy nhiên, thay vì có một MKPolyline, tôi muốn có lớp Mô hình của riêng mình phù hợp với giao thức MKOverlay được thêm vào bản đồ để tôi có thể truy cập các thuộc tính mô hình khi tạo chế độ xem tương ứng trong mapView: viewForOverlay.

Vấn đề là tôi không thể tìm cách để kế thừa từ MKPolyline vì nó không có bất kỳ phương thức init nào mà tôi có thể gọi từ init của lớp con. Bạn chỉ có thể tạo chúng bằng cách sử dụng các phương pháp tiện lợi.

Làm cách nào tôi có thể tập hợp các thuộc tính mô hình và hành vi MKPolyline?

Trả lời

4

Bạn có thể set an associated object attribute của lớp học. Điều này cho phép bạn liên kết một biến cá thể với một lớp hiện có. Hãy chắc chắn rằng bạn làm sạch đúng cách sau khi chính mình.

2

Đúng là MKPolyline không có phương thức init riêng. Trong thực tế, lớp duy nhất trong chuỗi kế thừa của MKPolyline có một phương thức init là NSObject.

Vì vậy, khi tôi subclassed MKPolyline Tôi chỉ overrode phương pháp init xác định bởi NSObject ...

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

Sau đó, khi bạn muốn nhanh chóng lớp con của bạn với tọa độ bạn có thể làm điều gì đó như thế này ...

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

với đó là không có cách nào để đặt tọa độ, vì tọa độ là thuộc tính chỉ đọc và chỉ có thể được đặt bằng phương thức tiện lợi. Tôi cũng đã hy vọng phân lớp MKPolyline, chỉ để thêm một phần thông tin vào nó, nhưng có vẻ như tôi không thể làm điều này. – GendoIkari

+0

Có một cách để đặt tọa độ trên một phân lớp của MKPolyline, đây là đoạn mã ... MyPolyline * myPolyline = (MyPolyline *) [MyPolyline polylineWithCoordinates: coordinate count: coordinateCount]; –

+3

polylineWithCoordinates luôn trả về MKPolyline ... nó sẽ không bao giờ trả về MyPolyline. Vì vậy, ngay cả khi bạn cast nó như thế, tất cả các bạn đang làm là nói với trình biên dịch rằng nó là một MyPolyline. Trong bộ nhớ nó vẫn sẽ thực sự là một MKPolyline. – GendoIkari

2

CẬP NHẬT: Có một tùy chọn khác (có thể tốt hơn) để sử dụng tính năng chuyển tiếp tin nhắn cho điều này (như -forwardingTargetForSelector hoặc nội dung).

Tôi đã có cùng một vấn đề hôm nay nhưng đã đưa ra giải pháp khác. Thay vì sử dụng đề xuất của Wayne liên quan đến công cụ thuộc tính đối tượng tôi chỉ đóng gói MKPolyline trong một lớp khác và chuyển các thông điệp của giao thức MKOverlay cho nó.

Vì vậy, tôi đã có một cái gì đó giống như trong .h:

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

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

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

@end 

Và trong .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 

Vì vậy MyOverlay cư xử như MKPolyline (phù hợp với MKOverlay) và tại cùng một thời gian tôi có thể làm bất cứ điều gì với nó, có nhiều tài sản như tôi cần.

+0

Có thể người downvote giải thích những gì sai với câu trả lời này? –

7

đang MANIAK_dobrii là con đường để đi nhưng tôi thấy tôi đã phải thực hiện một số phương pháp MKMultiPoint thêm để làm cho nó hoạt động, đây là hoàn chỉnh header và thực hiện tác phẩm của tôi cho một lớp AnchorLine tôi đã sử dụng: -

Tiêu đề AnchorLine .h

#import <MapKit/MapKit.h> 

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

@property (nonatomic, retain) MKPolyline* polyline; 

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

AnchorLine.m Thực hiện

#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 

Hy vọng rằng sẽ giúp một ai đó.

0

Những gì được đề cập ở đây cho đến nay vẫn chưa hoàn toàn phù hợp với tôi nhưng tôi đã quản lý một giải pháp dựa trên các câu trả lời khác và một số nghiên cứu độc lập. Tôi không chắc chắn 100% trong điều này nhưng bạn có thể bỏ một MKPolyline thành một lớp con tùy chỉnh chỉ nếu bạn sử dụng lệnh gọi phương thức tĩnh gọi phương thức 'init' bên trong.

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

trên sẽ không làm việc vì polylineWithCoordinates chỉ cấp phát bộ nhớ cho một đối tượng MKPolyline và không CustomPolyline. Tôi nghi ngờ những gì đang xảy ra bên trong là polylineWithCoordinates gọi phương thức khởi tạo khác theo cách tương tự như: [MKPolyline otherInitMethod:...]. Và nó không phân bổ số lượng bộ nhớ thích hợp bởi vì nó hiện đang sử dụng một cuộc gọi phương thức tĩnh MKPolyline và không phải là cuộc gọi tĩnh CustomPolyline của chúng tôi.

Tuy nhiên nếu chúng ta sử dụng

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

Nó không làm việc. Tôi nghĩ rằng điều này là do polylineWithPoints đang sử dụng trình khởi tạo trả về một id không chỉ là chuỗi cuộc gọi phương thức khác. Và vì chúng tôi đã gọi nó bằng cách sử dụng lớp CustomPolyline trình khởi tạo phân bổ bộ nhớ cho CustomPolyline không phải MKPolyline.

Tôi có thể hoàn toàn sai về lý do tại sao nó hoạt động. Nhưng tôi đã thử nghiệm này và nó có vẻ làm việc tốt. MKPolygon có thể được mở rộng theo cách tương tự. Trong trường hợp đó tôi nghĩ rằng phương pháp tĩnh đúng để sử dụng là MKPolygon polygonWithCoordinates:points count:pointSet.count]]

thực hiện của tôi để tham khảo:

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 Vấn đề

#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 
Các vấn đề liên quan