我正在使用showAnnotations方法在iOS7的MKMapView
上显示我的标记。有时它可以完美工作并显示所有注释,但有时会出现EXEC_BAD_ACCESS
错误。
这是我的代码。
NSArray *annotations = MapView.annotations;
_mapNeedsPadding = YES;
[MapView showAnnotations:annotations animated:YES];
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
if(_mapNeedsPadding){
[mapView setVisibleMapRect:mapView.visibleMapRect edgePadding:UIEdgeInsetsMake(100, 20, 10, 10) animated:YES];
_mapNeedsPadding = NO;
}
}
最佳答案
在所示的代码中,您将获得EXC_BAD_ACCESS
,因为调用setVisibleMapRect
会导致 map 视图再次调用regionDidChangeAnimated
,从而开始无限递归。
即使您正在使用布尔标志_mapNeedsPadding
来防止这种递归,问题仍然在于,已在调用NO
后将该标志设置为setVisibleMapRect
(并且它已经调用了regionDidChangeAnimated
,并且该标志从未设置为NO
)。
因此,您的代码将调用setVisibleMapRect
,这将导致再次调用regionDidChangeAnimated
,从而导致无限递归,从而导致堆栈溢出,从而导致EXC_BAD_ACCESS
。
“快速修复”是在调用_mapNeedsPadding
之前设置setVisibleMapRect
:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
if(_mapNeedsPadding){
_mapNeedsPadding = NO; // <-- call BEFORE setVisibleMapRect
[mapView setVisibleMapRect:mapView.visibleMapRect edgePadding:UIEdgeInsetsMake(100, 20, 10, 10) animated:YES];
}
}
但是,我不建议从此开始。
相反,您应该根据要显示的注释手动计算
MKMapRect
并从主代码(而不是setVisibleMapRect:edgePadding:animated:
)中调用showAnnotations:animated:
。并且,不要在
regionDidChangeAnimated
中实现或做任何事情。例:
NSArray *annotations = MapView.annotations;
//_mapNeedsPadding = YES;
//[MapView showAnnotations:annotations animated:YES];
MKMapRect rectForAnns = MKMapRectNull;
for (id<MKAnnotation> ann in annotations)
{
MKMapPoint annPoint = MKMapPointForCoordinate(ann.coordinate);
MKMapRect annRect = MKMapRectMake(annPoint.x, annPoint.y, 1, 1);
if (MKMapRectIsNull(rectForAnns))
rectForAnns = annRect;
else
rectForAnns = MKMapRectUnion(rectForAnns, annRect);
}
UIEdgeInsets rectInsets = UIEdgeInsetsMake(100, 20, 10, 10);
[MapView setVisibleMapRect:rectForAnns edgePadding:rectInsets animated:YES];
//Do NOT implement regionDidChangeAnimated...
//- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
// if(_mapNeedsPadding){
// [mapView setVisibleMapRect:mapView.visibleMapRect edgePadding:UIEdgeInsetsMake(100, 20, 10, 10) animated:YES];
// _mapNeedsPadding = NO;
// }
//}