使用自定义覆盖从 plist 加载多个注释

Posted

技术标签:

【中文标题】使用自定义覆盖从 plist 加载多个注释【英文标题】:Multiple Annotations loaded from plist using custom overlays 【发布时间】:2012-10-04 15:38:52 【问题描述】:

我似乎无法弄清楚为什么我会收到此错误并难住了自己:

类 PlaceMark 的实例 0x7c763e0 在 key 时被释放 价值观察者仍然在其中注册。观察信息是 泄漏,甚至可能被错误地附着在其他物体上。 在 NSKVODeallocateBreak 上设置断点以在调试器中停止。 以下是当前观察信息:<NSKeyValueObservationInfo 0x7c77220> ( <NSKeyValueObservance 0x7c77070: Observer: 0x7ba10c0, Key path: coordinate, Options: <New: NO, Old: NO, Prior: YES> Context: 0x0, Property: 0x7c76b00>)

我的 Plist 示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>caloosahatchee</key>
<array>
    <dict>
        <key>name</key>
        <string>Punta Rassa Boat Ramp</string>
        <key>latitude</key>
        <string>26.48444444444444</string>
        <key>longitude</key>
        <string>-82.010277777777778</string>
        <key>coordinates</key>
        <string>N26 29 04 W81 00 37</string>
        <key>description</key>
        <string>Boat ramp with fish cleaning station and several long docks.\n(239) 533-7275</string>
        <key>icons</key>
        <string>CFILH</string>
    </dict>
    <dict>
        <key>name</key>
        <string>Cape Harbour</string>
        <key>latitude</key>
        <string>26.48015</string>
        <key>longitude</key>
        <string>-81.96936</string>
        <key>coordinates</key>
        <string>N26 32 38 W82 00 28</string>
        <key>description</key>
        <string>Marina with bait/tackle shop, kayak rentals and access to restaurant and shops. Boat docks and paddle craft landing.\n(239) 945-4330</string>
        <key>icons</key>
        <string>FNLJI</string>
    </dict>
    <dict>
        <key>name</key>
        <string>Tarpon Point</string>
        <key>latitude</key>
        <string>26.53922222222222</string>
        <key>longitude</key>
        <string>-82.00027777777777778</string>
        <key>coordinates</key>
        <string>N26 32 21.2 W82 00 01</string>
        <key>description</key>
        <string>Full-service marina and resort with special kayak launch (fee), boat/kayak rentals, charters and ship’s store.\n(239) 542-6222</string>
        <key>icons</key>
        <string>FMNLJI</string>
    </dict>
</array>
</dict>
</plist>

这是我的viewForAnnotation和CallOutAccessory:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation: (id <MKAnnotation>)annotation 
MKPinAnnotationView *pinView = nil;
if(annotation != mapview.userLocation)

    static NSString *defaultPinID = @"pin";
    pinView = (MKPinAnnotationView *)[mapview dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
    if ( pinView == nil ) pinView = [[[MKPinAnnotationView alloc]
                                      initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
    pinView.pinColor = MKPinAnnotationColorGreen;
    pinView.canShowCallout = YES;
    pinView.animatesDrop = YES;
    pinView.rightCalloutAccessoryView = [[UIButton buttonWithType:UIButtonTypeDetailDisclosure] retain];
    pinView.backgroundColor = [UIColor clearColor];


 else 

    CLLocationCoordinate2D userLoc;
    userLoc.latitude = mapview.userLocation.location.coordinate.latitude;
    userLoc.longitude = mapview.userLocation.location.coordinate.longitude;

    int degrees = userLoc.latitude;
    double decimal = fabs(userLoc.latitude - degrees);
    int minutes = decimal * 60;
    double seconds = decimal * 3600 - minutes * 60;
    NSString *lat = [NSString stringWithFormat:@"%d° %d' %1.4f\"", degrees, minutes, seconds];

    degrees = userLoc.longitude;
    decimal = fabs(userLoc.longitude - degrees);
    minutes = decimal * 60;
    seconds = decimal * 3600 - minutes * 60;
    NSString *longt = [NSString stringWithFormat:@"%d° %d' %1.4f\"", degrees, minutes, seconds];

    NSString *coordinate_l = [NSString stringWithFormat:@"%@ %@ %@",lat,@", ",longt];

    [mapview.userLocation setSubtitle:coordinate_l];
    [mapview.userLocation setTitle:@"Coordinates:"];

return pinView;


- (void)mapView:(MKMapView *)mapView pinView:(MKAnnotationView *)pinView calloutAccessoryControlTapped:(UIControl *)control 
dViewController = [[detailViewController alloc] initWithNibName:@"detailViewController" bundle:nil];

PlaceMark *theAnnotation = (PlaceMark *) pinView.annotation;

dViewController.descriptiontext = theAnnotation.description;
dViewController.titletext = theAnnotation.title;
dViewController.icontext = theAnnotation.text;

[self presentModalViewController:dViewController animated:true];
[dViewController release];

这是我的 PlaceMark 类:

@interface PlaceMark : NSObject <MKAnnotation> 
CLLocationCoordinate2D coordinate;

NSString *currentSubTitle;
NSString *currentTitle;
NSString *currentDescription;
NSString *currentText;


@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *currentTitle;
@property (nonatomic, copy) NSString *currentSubTitle;
@property (nonatomic, copy) NSString *currentDescription;
@property (nonatomic, copy) NSString *currentText;

- (NSString *)title;
- (NSString *)subtitle;
- (NSString *)description;
- (NSString *)text;

-(id)initWithCoordinate:(CLLocationCoordinate2D) c;

@end

@implementation PlaceMark
@synthesize coordinate,currentTitle,currentSubTitle,currentDescription,currentText;

- (NSString *)subtitle
return currentSubTitle;

- (NSString *)title
return currentTitle;

- (NSString *)description
return currentDescription;

- (NSString *)text
return currentText;


-(id)initWithCoordinate:(CLLocationCoordinate2D) c
coordinate=c;
NSLog(@"%f,%f",c.latitude,c.longitude);
return self;


- (void)dealloc

self.currentDescription=nil;
self.currentText=nil;
self.currentSubTitle=nil;
self.currentTitle=nil;

[super dealloc];


@end

注解的自定义加载函数:

- (void)loadLeeAnnotations
//retrieve path of plist file and populate relevant types with its information
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Coordinates" ofType:@"plist"];
NSDictionary *rootPlistDict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
NSMutableArray *arboAnnotations = [[NSMutableArray alloc] init];

//NSMutableDictionary *arboDict = [rootPlistDict objectForKey:key];
NSArray *annotationsArray = [rootPlistDict objectForKey:@"lee"];

CLLocationCoordinate2D workingCoordinate;
for(NSDictionary *annotationContainerDict in annotationsArray)

    workingCoordinate.latitude = [[annotationContainerDict objectForKey:@"latitude"] doubleValue];
    workingCoordinate.longitude = [[annotationContainerDict objectForKey:@"longitude"] doubleValue];
     //NSLog(@"latitude: %f Longitude %f",workingCoordinate.latitude,workingCoordinate.longitude);
    PlaceMark *addAnn = [[[PlaceMark alloc] initWithCoordinate:workingCoordinate] autorelease];
    [addAnn setCurrentTitle:[annotationContainerDict objectForKey:@"name"]];
    [addAnn setCurrentSubTitle:[annotationContainerDict objectForKey:@"coodinates"]];
    [addAnn setCurrentText:[annotationContainerDict objectForKey:@"icons"]];
    [addAnn setCurrentDescription: [annotationContainerDict objectForKey:@"description"]];
    [arboAnnotations addObject:addAnn];

//for
//NSLog(@"The content of array is %@",arboAnnotations);
mapview.delegate = self;
[mapview addAnnotations:arboAnnotations];
[arboAnnotations release];

【问题讨论】:

【参考方案1】:

该错误通常意味着坐标无效。 纬度必须介于 -90 到 90 之间,经度必须介于 -180 到 180 之间。

也许代码使用纬度的经度值,反之亦然(或者 plist 中的值可能是向后的)?

【讨论】:

我不认为这是我的问题,因为其中一个叠加层正在正确加载。我在上面的代码中添加了我的 plist。 “覆盖”是指 PlaceMark 注释吗?您能说明您是如何创建地标并将其添加到地图的吗? 我在上面添加了自定义加载注释函数,当他们从 PickerView didSelectRow 中选择要查看的地图时运行该函数 在代码中,您将获得“lee”的地标,我认为它与“caloosahatchee”不同。当您 NSLog 坐标时,纬度/经度是否正确?看起来不正确的一件事是[addAnn release]; 行。你不应该这样做,因为你已经在 alloc+init 行中调用了autorelease。删除[addAnn release]; lee 也在 plist 中,我只剪掉了 3 个 plist 项目。感谢发布捕获【参考方案2】:

我把它修好了谢谢安娜!关于删除的评论

[addAnn release];

自定义注解加载类似乎已经解决了这个问题。现在我需要让我的注释弹出窗口显示它们似乎不可点击并且当我点击它们时什么也不做。

【讨论】:

以上是关于使用自定义覆盖从 plist 加载多个注释的主要内容,如果未能解决你的问题,请参考以下文章

保存/加载自定义对象数组到 plist Objective C

将项目添加到 .plist 并在自定义 UITableViewCell 中显示

将数组内容(自定义类型)写入 plist 作为 swift 中的键控数组

如何使用 plist 中的数据阻止或禁用 Tableview 中的自定义单元格?

多个自定义 UITableViewCell 相互覆盖 Swift

用于地图注释随机化的 iOS 自定义图标