MKMapKit - 循环 MKAnnotations 时的 EXC_BAD_ACCESS

发布于 2024-11-12 07:49:57 字数 2953 浏览 4 评论 0原文

我已经被这个 EXC_BAD_ACCESS 错误困住了两天了。我有一个 reloadAnnotations 方法,可以在添加新注释之前删除所有注释。在删除注释之前,此方法应该检查新集是否包含相同的位置,这样就不会删除并重新添加它。但是,当我尝试追踪当前注释标题时,我收到此错误 Thread 1: Program returned signal: "EXC_BAD_ACCESS"

当我在调试器中查看注释时,标题属性显示“无效摘要” ”。它一定是由于未保留某个值而引起的,但我已经尝试了所有方法,但无法弄清楚。

为什么我无法将注释标题记录到 NSLog?

为什么我无法将每个标题和坐标与其他对象进行比较?

BrowseController.m

-(void)reloadAnnotations
{
    NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:10];
    for (id annotation in _mapView.annotations) {
        if (annotation != _mapView.userLocation) {
            //ParkAnnotation *pa = (ParkAnnotation *)annotation;
            ParkAnnotation *pa = annotation;
            NSLog(@"pa.title %@", pa.title); // Thread 1: Program received signal: "EXC_BAD_ACCESS"
            [toRemove addObject:annotation];
        }
    }
    // DON'T REMOVE IT IF IT'S ALREADY ON THE MAP!!!!!! 
    for(RKLocation *loc in locations) 
    {
        CLLocationCoordinate2D location;
        location.latitude = (double)[loc.lat doubleValue];
        location.longitude = (double)[loc.lng doubleValue];
        ParkAnnotation *parkAnnotation = [[ParkAnnotation alloc] initWithTitle:loc.name andCoordinate:location];      
        [_mapView addAnnotation:parkAnnotation];
    }
    [_mapView removeAnnotations:toRemove];
}



- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
    NSLog(@"BrowseViewController map viewForAnnotation");
    MKPinAnnotationView *pin = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier: @"anIdentifier"];

    if (pin == nil){
        pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                               reuseIdentifier: @"anIdentifier"] autorelease];

        pin.pinColor = MKPinAnnotationColorRed;
        pin.animatesDrop = YES;
        pin.canShowCallout = YES;
    }
    else{
        pin.annotation = annotation;
    }
    return pin;
    }

ParkAnnotation.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface ParkAnnotation : NSObject <MKAnnotation> {

    NSString *title;
    CLLocationCoordinate2D coordinate;

}


@property (nonatomic, copy) NSString *title;  
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;

@end

ParkAnnotation.m (编辑:请参阅下面沃尔夫冈的评论)

#import "ParkAnnotation.h"
@implementation ParkAnnotation
@synthesize title, coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
    self = [super init];
    if (self) { 
        title = ttl;
        coordinate = c2d;    
    } 
    return self;
}
- (void)dealloc {
    [title release];
    [super dealloc];
}
@end

I've been stuck on this EXC_BAD_ACCESS error 2 days now. I have a reloadAnnotations method that removes all annotations before adding new annotations. Before removing the annotation this method should be checking to see if the new set contains the same location so it's not removed and re-added. But as soon as I try to trace out the current annotation title I get this error Thread 1: Program received signal: "EXC_BAD_ACCESS"

And when I view the annotation in the debugger the title property says "Invalid Summary". It must be caused by a value not being retained but I've tried everything and can't figure it out.

Why can't I log the annotation title to NSLog?

And why can't I compare each title and coords to other objects?

BrowseController.m

-(void)reloadAnnotations
{
    NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:10];
    for (id annotation in _mapView.annotations) {
        if (annotation != _mapView.userLocation) {
            //ParkAnnotation *pa = (ParkAnnotation *)annotation;
            ParkAnnotation *pa = annotation;
            NSLog(@"pa.title %@", pa.title); // Thread 1: Program received signal: "EXC_BAD_ACCESS"
            [toRemove addObject:annotation];
        }
    }
    // DON'T REMOVE IT IF IT'S ALREADY ON THE MAP!!!!!! 
    for(RKLocation *loc in locations) 
    {
        CLLocationCoordinate2D location;
        location.latitude = (double)[loc.lat doubleValue];
        location.longitude = (double)[loc.lng doubleValue];
        ParkAnnotation *parkAnnotation = [[ParkAnnotation alloc] initWithTitle:loc.name andCoordinate:location];      
        [_mapView addAnnotation:parkAnnotation];
    }
    [_mapView removeAnnotations:toRemove];
}



- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
    NSLog(@"BrowseViewController map viewForAnnotation");
    MKPinAnnotationView *pin = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier: @"anIdentifier"];

    if (pin == nil){
        pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                               reuseIdentifier: @"anIdentifier"] autorelease];

        pin.pinColor = MKPinAnnotationColorRed;
        pin.animatesDrop = YES;
        pin.canShowCallout = YES;
    }
    else{
        pin.annotation = annotation;
    }
    return pin;
    }

ParkAnnotation.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface ParkAnnotation : NSObject <MKAnnotation> {

    NSString *title;
    CLLocationCoordinate2D coordinate;

}


@property (nonatomic, copy) NSString *title;  
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;

@end

ParkAnnotation.m (edited: see Wolfgangs comments below )

#import "ParkAnnotation.h"
@implementation ParkAnnotation
@synthesize title, coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
    self = [super init];
    if (self) { 
        title = ttl;
        coordinate = c2d;    
    } 
    return self;
}
- (void)dealloc {
    [title release];
    [super dealloc];
}
@end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谁把谁当真 2024-11-19 07:49:57

尽管您已声明 title 具有 copy 类型属性,但它永远不会被复制,因为您不使用 setter 方法并直接分配。您甚至在没有所有权的情况下释放它。改成这样,

title = [ttl copy];

Although you have declared title has a copy type property, it never is copied as you don't use the setter method and directly assigned. You are even releasing it without ownership. Change it like this,

title = [ttl copy];
缱倦旧时光 2024-11-19 07:49:57

ParkAnnotation.m 中的初始化程序不是按照 ObjC 约定编写的。 self 变量永远不会被设置,类的指定初始值设定项应遵循以下模式:

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

由于 self 未设置,因此调用方中使用的访问器方法将失败;当尝试从另一个类访问对象内部的属性时,容器对象(在 ParkAnnotation.m 内用 self 引用)将为 nil 或某个虚假值。

The initializer in ParkAnnotation.m isn't written following ObjC conventions. The self variable is never set, the designated initializer of a class should follow the following pattern:

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

Since self is not set, the accessor methods used in the caller will fail; the container object (inside ParkAnnotation.m referenced with self) will be nil or some bogus value when trying to access a property inside the object from another class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文