使用 dequeueReusableAnnotationViewWithIdentifier 时的 EXC_BAD_ACCESS

发布于 2024-11-30 18:12:52 字数 5640 浏览 1 评论 0原文

由于某种原因,我的地图视图和注释在没有 dequeueReusableAnnotationViewWithIdentifier 的情况下工作正常,但是一旦我取消注释并尝试使用它,我的程序就会不断崩溃。该错误是 EXC_BAD_ACCESS。

#import "ThirdViewController.h"
#import "MKMapView+ZoomLevel.h"
#import "CalcBlockID.h"
#import "CalcBorderBlocks.h"
#import "MakeBlocksQuery.h"
#import "Block.h"


@implementation ThirdViewController
@synthesize mapView = mapView_;
@synthesize zoomLabel = zoomLabel_;

@synthesize blockID = blockID_;
@synthesize blockArray = blockArray_;
@synthesize query = query_;

static ThirdViewController *currentInstance;

 - (void)viewDidLoad {
   [super viewDidLoad];
   blockStorage_ = [BlockStorage instance];
   restDelegate_ = [RESTDelegate instance];
   currentInstance = self;

   self.mapView.delegate = self;
   self.mapView.showsUserLocation = YES;
}

- (void)didReceiveMemoryWarning {
  // Releases the view if it doesn't have a superview.
  [super didReceiveMemoryWarning];

  // Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
  [super viewDidUnload];
  self.mapView = nil;
  self.zoomLabel = nil;

  self.blockID = nil;
  self.blockArray = nil;
  self.query = nil;
}

- (void)dealloc {
  [mapView_ release];
  [zoomLabel_ release];

  [blockID_ release];
  [blockArray_ release];
  [query_ release];
  [super dealloc];
}

+ (ThirdViewController *)returnSelf {
  return currentInstance;
}

#pragma mark - Key Methods

// Called when objects are recieved from RESTDelegate class
- (void)addAnnotations:(NSArray *)blocks {
  [self.mapView addAnnotations:blocks];
}

// Called whenever the current map view region is changed.
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
  latitude_ = self.mapView.region.center.latitude;
  longitude_ = self.mapView.region.center.longitude;
  zoom_ = [self.mapView zoomLevel];

  CalcBlockID *calcBlockID = [[CalcBlockID alloc] init];
  self.blockID = [calcBlockID calcWithLat:latitude_ andLong:longitude_ andZoom:zoom_];
  [calcBlockID release];

  CalcBorderBlocks *calcBorderBlocks = [[CalcBorderBlocks alloc] init];
  self.blockArray = [calcBorderBlocks calcWithBlockID:self.blockID];
  [calcBorderBlocks release];

  MakeBlocksQuery *makeBlocksQuery = [[MakeBlocksQuery alloc] init];
  self.query = [makeBlocksQuery makeWithBlockArray:self.blockArray];
  [makeBlocksQuery release];

  if (self.query) {
    [restDelegate_ loadBlocksWithQuery:self.query];
  }
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
  // If annotation is of user's location, return nil to use default view.
  if ([annotation isKindOfClass:[MKUserLocation class]]) {
    return nil;
  }

  // Try to dequeue an existing pin.
  static NSString *viewIdentifier = @"annotationView";
  MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier];

  if (!pinAnnotationView) {
    pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier];
    pinAnnotationView.pinColor = MKPinAnnotationColorPurple; // PURPLE!
  } else {
    pinAnnotationView.annotation = annotation;
  }
  return [pinAnnotationView autorelease];
}

@end

这是崩溃报告之一:

0x0163408c  <+0000>  mov    0x8(%esp),%ecx
0x01634090  <+0004>  mov    0x4(%esp),%eax
0x01634094  <+0008>  test   %eax,%eax
0x01634096  <+0010>  je     0x16340ea <objc_msgSend+94>
0x01634098  <+0012>  mov    (%eax),%edx
0x0163409a  <+0014>  push   %edi
0x0163409b  <+0015>  mov    0x8(%edx),%edi
0x0163409e  <+0018>  push   %esi
0x0163409f  <+0019>  mov    (%edi),%esi
0x016340a1  <+0021>  mov    %ecx,%edx
0x016340a3  <+0023>  shr    $0x2,%edx
0x016340a6  <+0026>  and    %esi,%edx
0x016340a8  <+0028>  mov    0x8(%edi,%edx,4),%eax
0x016340ac  <+0032>  test   %eax,%eax
0x016340ae  <+0034>  je     0x16340b9 <objc_msgSend+45>
0x016340b0  <+0036>  cmp    (%eax),%ecx
0x016340b2  <+0038>  je     0x16340d0 <objc_msgSend+68>
0x016340b4  <+0040>  add    $0x1,%edx
0x016340b7  <+0043>  jmp    0x16340a6 <objc_msgSend+26>
0x016340b9  <+0045>  pop    %esi
0x016340ba  <+0046>  pop    %edi
0x016340bb  <+0047>  mov    0x4(%esp),%eax
0x016340bf  <+0051>  mov    (%eax),%eax
0x016340c1  <+0053>  jmp    0x16340d9 <objc_msgSend+77>
0x016340c3  <+0055>  nopw   0x0(%eax,%eax,1)
0x016340c9  <+0061>  nopl   0x0(%eax)
0x016340d0  <+0068>  mov    0x8(%eax),%eax
0x016340d3  <+0071>  pop    %esi
0x016340d4  <+0072>  pop    %edi
0x016340d5  <+0073>  xor    %edx,%edx
0x016340d7  <+0075>  jmp    *%eax
0x016340d9  <+0077>  sub    $0x4,%esp
0x016340dc  <+0080>  push   %ecx
0x016340dd  <+0081>  push   %eax
0x016340de  <+0082>  call   0x16211ae <_class_lookupMethodAndLoadCache>
0x016340e3  <+0087>  add    $0xc,%esp
0x016340e6  <+0090>  xor    %edx,%edx
0x016340e8  <+0092>  jmp    *%eax
0x016340ea  <+0094>  call   0x16340ef <objc_msgSend+99>
0x016340ef  <+0099>  pop    %edx
0x016340f0  <+0100>  mov    0xbba21(%edx),%eax
0x016340f6  <+0106>  test   %eax,%eax
0x016340f8  <+0108>  je     0x1634100 <objc_msgSend+116>
0x016340fa  <+0110>  mov    %eax,0x4(%esp)
0x016340fe  <+0114>  jmp    0x1634098 <objc_msgSend+12>
0x01634100  <+0116>  mov    $0x0,%edx
0x01634105  <+0121>  ret    
0x01634106  <+0122>  xchg   %ax,%ax

For some reason my mapview and annotations work fine without dequeueReusableAnnotationViewWithIdentifier, but as soon as I uncomment it and try to use it my program keeps crashing. The error is an EXC_BAD_ACCESS.

#import "ThirdViewController.h"
#import "MKMapView+ZoomLevel.h"
#import "CalcBlockID.h"
#import "CalcBorderBlocks.h"
#import "MakeBlocksQuery.h"
#import "Block.h"


@implementation ThirdViewController
@synthesize mapView = mapView_;
@synthesize zoomLabel = zoomLabel_;

@synthesize blockID = blockID_;
@synthesize blockArray = blockArray_;
@synthesize query = query_;

static ThirdViewController *currentInstance;

 - (void)viewDidLoad {
   [super viewDidLoad];
   blockStorage_ = [BlockStorage instance];
   restDelegate_ = [RESTDelegate instance];
   currentInstance = self;

   self.mapView.delegate = self;
   self.mapView.showsUserLocation = YES;
}

- (void)didReceiveMemoryWarning {
  // Releases the view if it doesn't have a superview.
  [super didReceiveMemoryWarning];

  // Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
  [super viewDidUnload];
  self.mapView = nil;
  self.zoomLabel = nil;

  self.blockID = nil;
  self.blockArray = nil;
  self.query = nil;
}

- (void)dealloc {
  [mapView_ release];
  [zoomLabel_ release];

  [blockID_ release];
  [blockArray_ release];
  [query_ release];
  [super dealloc];
}

+ (ThirdViewController *)returnSelf {
  return currentInstance;
}

#pragma mark - Key Methods

// Called when objects are recieved from RESTDelegate class
- (void)addAnnotations:(NSArray *)blocks {
  [self.mapView addAnnotations:blocks];
}

// Called whenever the current map view region is changed.
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
  latitude_ = self.mapView.region.center.latitude;
  longitude_ = self.mapView.region.center.longitude;
  zoom_ = [self.mapView zoomLevel];

  CalcBlockID *calcBlockID = [[CalcBlockID alloc] init];
  self.blockID = [calcBlockID calcWithLat:latitude_ andLong:longitude_ andZoom:zoom_];
  [calcBlockID release];

  CalcBorderBlocks *calcBorderBlocks = [[CalcBorderBlocks alloc] init];
  self.blockArray = [calcBorderBlocks calcWithBlockID:self.blockID];
  [calcBorderBlocks release];

  MakeBlocksQuery *makeBlocksQuery = [[MakeBlocksQuery alloc] init];
  self.query = [makeBlocksQuery makeWithBlockArray:self.blockArray];
  [makeBlocksQuery release];

  if (self.query) {
    [restDelegate_ loadBlocksWithQuery:self.query];
  }
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
  // If annotation is of user's location, return nil to use default view.
  if ([annotation isKindOfClass:[MKUserLocation class]]) {
    return nil;
  }

  // Try to dequeue an existing pin.
  static NSString *viewIdentifier = @"annotationView";
  MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier];

  if (!pinAnnotationView) {
    pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier];
    pinAnnotationView.pinColor = MKPinAnnotationColorPurple; // PURPLE!
  } else {
    pinAnnotationView.annotation = annotation;
  }
  return [pinAnnotationView autorelease];
}

@end

Here's one of the crash reports:

0x0163408c  <+0000>  mov    0x8(%esp),%ecx
0x01634090  <+0004>  mov    0x4(%esp),%eax
0x01634094  <+0008>  test   %eax,%eax
0x01634096  <+0010>  je     0x16340ea <objc_msgSend+94>
0x01634098  <+0012>  mov    (%eax),%edx
0x0163409a  <+0014>  push   %edi
0x0163409b  <+0015>  mov    0x8(%edx),%edi
0x0163409e  <+0018>  push   %esi
0x0163409f  <+0019>  mov    (%edi),%esi
0x016340a1  <+0021>  mov    %ecx,%edx
0x016340a3  <+0023>  shr    $0x2,%edx
0x016340a6  <+0026>  and    %esi,%edx
0x016340a8  <+0028>  mov    0x8(%edi,%edx,4),%eax
0x016340ac  <+0032>  test   %eax,%eax
0x016340ae  <+0034>  je     0x16340b9 <objc_msgSend+45>
0x016340b0  <+0036>  cmp    (%eax),%ecx
0x016340b2  <+0038>  je     0x16340d0 <objc_msgSend+68>
0x016340b4  <+0040>  add    $0x1,%edx
0x016340b7  <+0043>  jmp    0x16340a6 <objc_msgSend+26>
0x016340b9  <+0045>  pop    %esi
0x016340ba  <+0046>  pop    %edi
0x016340bb  <+0047>  mov    0x4(%esp),%eax
0x016340bf  <+0051>  mov    (%eax),%eax
0x016340c1  <+0053>  jmp    0x16340d9 <objc_msgSend+77>
0x016340c3  <+0055>  nopw   0x0(%eax,%eax,1)
0x016340c9  <+0061>  nopl   0x0(%eax)
0x016340d0  <+0068>  mov    0x8(%eax),%eax
0x016340d3  <+0071>  pop    %esi
0x016340d4  <+0072>  pop    %edi
0x016340d5  <+0073>  xor    %edx,%edx
0x016340d7  <+0075>  jmp    *%eax
0x016340d9  <+0077>  sub    $0x4,%esp
0x016340dc  <+0080>  push   %ecx
0x016340dd  <+0081>  push   %eax
0x016340de  <+0082>  call   0x16211ae <_class_lookupMethodAndLoadCache>
0x016340e3  <+0087>  add    $0xc,%esp
0x016340e6  <+0090>  xor    %edx,%edx
0x016340e8  <+0092>  jmp    *%eax
0x016340ea  <+0094>  call   0x16340ef <objc_msgSend+99>
0x016340ef  <+0099>  pop    %edx
0x016340f0  <+0100>  mov    0xbba21(%edx),%eax
0x016340f6  <+0106>  test   %eax,%eax
0x016340f8  <+0108>  je     0x1634100 <objc_msgSend+116>
0x016340fa  <+0110>  mov    %eax,0x4(%esp)
0x016340fe  <+0114>  jmp    0x1634098 <objc_msgSend+12>
0x01634100  <+0116>  mov    $0x0,%edx
0x01634105  <+0121>  ret    
0x01634106  <+0122>  xchg   %ax,%ax

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

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

发布评论

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

评论(1

述情 2024-12-07 18:12:52

问题在于您过度释放了出列的注释,因为您的释放不平衡。

MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier]; // +0 retain count

if (!pinAnnotationView) {
    pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier]; // +1 retain count
    // ...
}
return [pinAnnotationView autorelease]; // release!

所以你应该使用

[[self.mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier] retain]

[[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier] autorelease]
// and don't -autorelease later.

The problem is that you're over-releasing the dequeued annotation because you have an unbalanced release.

MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier]; // +0 retain count

if (!pinAnnotationView) {
    pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier]; // +1 retain count
    // ...
}
return [pinAnnotationView autorelease]; // release!

So instead you should use

[[self.mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier] retain]

or

[[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier] autorelease]
// and don't -autorelease later.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文