MKMapKit - 循环 MKAnnotations 时的 EXC_BAD_ACCESS
我已经被这个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尽管您已声明
title
具有copy
类型属性,但它永远不会被复制,因为您不使用 setter 方法并直接分配。您甚至在没有所有权的情况下释放它。改成这样,Although you have declared
title
has acopy
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,ParkAnnotation.m 中的初始化程序不是按照 ObjC 约定编写的。 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:
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.