Ответ 1
_calloutAnnotation
не содержит аннотаций. Я думаю, что у вас есть код вроде этого @prorerty (weak, nonatomic) MKAnnotation * calloutAnnotation;
, изменяющий weak
на strong
, должен помочь.
У меня есть приложение для отображения карты и пользовательской аннотации. Мое приложение вылетает, когда пользователь коснется аннотации. Это происходит только в iOS 7. Он отлично работает с iOS 6 и iOS 5.
Ниже приведен отчет о сбое, который отображается в консоли:
ERROR: Trying to select an annotation which has not been added
-[__NSSetM coordinate]: unrecognized selector sent to instance 0x18c9d580
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSetM coordinate]: unrecognized selector sent to instance 0x18c9d580'
*** First throw call stack:
(
0 CoreFoundation 0x020415e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x016918b6 objc_exception_throw + 44
2 CoreFoundation 0x020de903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0203190b ___forwarding___ + 1019
4 CoreFoundation 0x0206e46e __forwarding_prep_1___ + 14
5 MapKit 0x000de10c _Z21_insertionNodeForItemP11objc_objectP14MKQuadTrieNode + 50
6 MapKit 0x000de428 _Z9_containsP11objc_objectP14MKQuadTrieNode + 27
7 MapKit 0x000de8ed -[MKQuadTrie contains:] + 39
8 MapKit 0x000d4918 -[MKAnnotationManager selectAnnotation:animated:avoid:] + 116
9 MapKit 0x00090789 -[MKMapView handleTap:] + 541
10 UIKit 0x0056ae8c _UIGestureRecognizerSendActions + 230
11 UIKit 0x00569b00 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383
12 UIKit 0x0056b56d -[UIGestureRecognizer _delayedUpdateGesture] + 60
13 UIKit 0x0056eacd ___UIGestureRecognizerUpdate_block_invoke + 57
14 UIKit 0x0056ea4e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317
15 UIKit 0x00565148 _UIGestureRecognizerUpdate + 199
16 CoreFoundation 0x020094ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
17 CoreFoundation 0x0200941f __CFRunLoopDoObservers + 399
18 CoreFoundation 0x01fe7344 __CFRunLoopRun + 1076
19 CoreFoundation 0x01fe6ac3 CFRunLoopRunSpecific + 467
20 CoreFoundation 0x01fe68db CFRunLoopRunInMode + 123
21 GraphicsServices 0x01f6c9e2 GSEventRunModal + 192
22 GraphicsServices 0x01f6c809 GSEventRun + 104
23 UIKit 0x001f2d3b UIApplicationMain + 1225
24 CustomMKAnnotationView 0x0000285a main + 170
25 CustomMKAnnotationView 0x000027a5 start + 53
)
libc++abi.dylib: terminating with uncaught exception of type NSException
И я создал код следующим образом:
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[BasicMapAnnotation class]])
{
if (_calloutAnnotation.coordinate.latitude == view.annotation.coordinate.latitude&&
_calloutAnnotation.coordinate.longitude == view.annotation.coordinate.longitude)
{
return;
}
if (_calloutAnnotation)
{
[mapView removeAnnotation:_calloutAnnotation];
_calloutAnnotation = nil;
}
_calloutAnnotation = [[[CalloutMapAnnotation alloc]
initWithLatitude:view.annotation.coordinate.latitude
andLongitude:view.annotation.coordinate.longitude]autorelease];
[mapView addAnnotation:_calloutAnnotation];
[mapView setCenterCoordinate:_calloutAnnotation.coordinate animated:YES];
}else
{
if([delegate respondsToSelector:@selector(customMKMapViewDidSelectedWithInfo:)])
{
[delegate customMKMapViewDidSelectedWithInfo:@"Annotation clicked"];
}
}
}
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if (_calloutAnnotation&& ![view isKindOfClass:[CallOutAnnotationVifew class]])
{
if (_calloutAnnotation.coordinate.latitude == view.annotation.coordinate.latitude&&
_calloutAnnotation.coordinate.longitude == view.annotation.coordinate.longitude)
{
[mapView removeAnnotation:_calloutAnnotation];
_calloutAnnotation = nil;
}
}
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[CalloutMapAnnotation class]])
{
CallOutAnnotationVifew *annotationView = (CallOutAnnotationVifew *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CalloutView"];
if (!annotationView)
{
annotationView = [[[CallOutAnnotationVifew alloc] initWithAnnotation:annotation reuseIdentifier:@"CalloutView"] autorelease];
JingDianMapCell *cell = [[[NSBundle mainBundle] loadNibNamed:@"JingDianMapCell" owner:self options:nil] objectAtIndex:0];
cell.titleLable.text = @"Testing";
[annotationView.contentView addSubview:cell];
}
return annotationView;
}else if ([annotation isKindOfClass:[BasicMapAnnotation class]])
{
MKAnnotationView *annotationView =[self.mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotation"];
if (!annotationView)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:@"CustomAnnotation"] autorelease];
annotationView.canShowCallout = NO;
annotationView.image = [UIImage imageNamed:@"pin.png"];
}
return annotationView;
}
return nil;
}
В didSelectAnnotationView и didDeselectAnnotationView Я добавляю новое представление аннотации и удаляю старый аннотационный вид. Представление аннотации - это пользовательский класс. И _calloutAnnotation - это объект CalloutMapAnnotation, который является классом NSObject для добавления аннотации.
_calloutAnnotation
не содержит аннотаций. Я думаю, что у вас есть код вроде этого @prorerty (weak, nonatomic) MKAnnotation * calloutAnnotation;
, изменяющий weak
на strong
, должен помочь.
ERROR: Trying to select an annotation which has not been added
Что здесь происходит, так это то, что пользователь нажимает "пузырь вызова", который на самом деле представляет собой аннотацию. Как часть этого, MapView сначала отменяет выбранную аннотацию, а затем выбирает аннотацию, которую пользователь нажал.
Однако, поскольку вы уже удалили выбранную аннотацию из карты на этапе удаления, ничего не нужно выбирать. Следовательно, сообщение "ERROR..." в отладчике.
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if (_calloutAnnotation&& ![view isKindOfClass:[CallOutAnnotationVifew class]])
{
if (_calloutAnnotation.coordinate.latitude == view.annotation.coordinate.latitude&&
_calloutAnnotation.coordinate.longitude == view.annotation.coordinate.longitude)
{
CalloutMapAnnotation *oldAnnotation = self.calloutAnnotation; //saving it to be removed from the map later
self.calloutAnnotation = nil; //setting to nil to know that we aren't showing a callout anymore
dispatch_async(dispatch_get_main_queue(), ^{
[mapView removeAnnotation:oldAnnotation]; //removing the annotation a bit later
});
}
}
}
Ваша проблема здесь:
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if (_calloutAnnotation&& ![view isKindOfClass:[CallOutAnnotationVifew class]])
{
if (_calloutAnnotation.coordinate.latitude == view.annotation.coordinate.latitude&&
_calloutAnnotation.coordinate.longitude == view.annotation.coordinate.longitude)
{
[mapView removeAnnotation:_calloutAnnotation];
//EDIT: This code is broken don't use it :)
//in iOS7.0 responder chain is changed a bit and you can't call this directly give it some time or remove this line and your crash will be gone ;)
// double delayInSeconds = 0.5;
// dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
// dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// _calloutAnnotation = nil;
// });
}
}
}