【问题标题】:MKMapView crashes with MKAnnotation with a custom iconMKMapView 与带有自定义图标的 MKAnnotation 一起崩溃
【发布时间】:2014-03-25 13:02:55
【问题描述】:

我正在尝试使用此代码将带有图标的 MKAnnotation 添加到地图中:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
@interface MapItem : NSObject<MKAnnotation>
{
    CLLocationCoordinate2D coordinate;
}
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, assign) NSString *itemtitle;
@property (nonatomic, assign) NSString *icon;
@property (nonatomic, assign) NSString *itemsubtitle;

- (NSString *)subtitle;
- (NSString *)title;
@end

#import "MapItem.h"

@implementation MapItem
@synthesize coordinate;
@synthesize icon;
@synthesize itemtitle;
@synthesize itemsubtitle;
-(NSString*) title{
    return self.itemtitle;
}
-(NSString*) subtitle{
    return self.itemsubtitle;
}

@end

这个来自 uiview:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    static NSString *identifier = @"MapItem";
    if ([annotation isKindOfClass:[MapItem class]]) {

        MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
            annotationView.enabled = YES;
            annotationView.canShowCallout = YES;

            annotationView.image = [UIImage imageNamed:((MapItem *)annotation).icon];



        } else {
            annotationView.annotation = annotation;
        }

        return annotationView;
    }

    return nil;
}

此代码正在运行,我可以在地图上看到注释,只有当我触摸地图时应用程序崩溃:

2014-03-25 14:53:30.540 PASIL[444:60b] -[__NSArrayM length]: unrecognized selector sent to instance 0x19f26230
2014-03-25 14:53:30.541 PASIL[444:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x19f26230'
*** First throw call stack:
(0x2dc59fd3 0x384d0ccf 0x2dc5d967 0x2dc5c253 0x2dbab7f8 0x2ee10e1f 0x2ee2a5c5 0x2ee2a943 0x304b081f 0x304b069b 0x304a51b3 0x304a4f9f 0x30478e2d 0x2dc2525b 0x2dc2472b 0x2dc22f1f 0x2db8df4f 0x2db8dd33 0x32ae6663 0x304d916d 0xea145 0x389ddab7)
libc++abi.dylib: terminating with uncaught exception of type NSException

添加注释:

  for (NSDictionary *dataDict in responseObject) {

            if([dataDict objectForKey:@"longitude"]!= (id)[NSNull null])
            {
                NSString *title=[dataDict objectForKey:@"title"];
                NSInteger report_type_id=[[dataDict objectForKey:@"report_type_id"] integerValue];
                float longitude=[[dataDict objectForKey:@"longitude"] floatValue];
                float latitude=[[dataDict objectForKey:@"latitude"] floatValue];
                CLLocationCoordinate2D coordinate;
                coordinate.latitude = latitude;
                coordinate.longitude = longitude;
                MapItem *annotation = [[MapItem alloc] init];
                annotation.coordinate=coordinate;
                annotation.itemtitle=title;
                switch(report_type_id)
                {
                    case 1:

                        annotation.itemsubtitle=@"Terror";
                        annotation.icon=@"map-legend-terrorism.png";
                        break;
                    case 2:

                        annotation.itemsubtitle=@"Traffic";
                        annotation.icon=@"map-legend-traffic.png";

                        break;
                    case 3:

                        annotation.itemsubtitle=@"Weather";
                        annotation.icon=@"map-legend-weather.png";
                        break;
                    case 4:

                        annotation.itemsubtitle=@"Crime";
                        annotation.icon=@"map-legend-crime.png";
                        break;

                }
                [self.mapView addAnnotation:annotation];
            }



        }

【问题讨论】:

  • 显示如何分配itemtitleitemsubtitle。看起来一个或两个都被分配了 NSMutableArray 而不是 NSString。
  • 这里是代码(注释出现在地图上——点击它时会崩溃,无论是否在注释上,在尝试缩放/移动时也会崩溃)
  • NSString *title = ... 行之后,放置这个NSLog,看看它写了什么:NSLog(@"title class = %@", [title class]);
  • 这是输出:title class= __NSCFString 但我无法将其转换为 NSString。评论标题分配正在解决问题。我会寻找一种投射方式。谢谢!
  • 所有注释都是那个类吗?

标签: ios objective-c mapkit mkannotation


【解决方案1】:

问题在于MapItem 类中的NSString 属性是如何声明的(不是标题之一是我的 cmets 中建议的数组):

@property (nonatomic, assign) NSString *itemtitle;
@property (nonatomic, assign) NSString *icon;
@property (nonatomic, assign) NSString *itemsubtitle;

通过将属性声明为assign,注释对象不会保留这些值,并且稍后(当地图视图尝试访问它时)内存指向其他东西(在您的情况下,它恰好是某个东西看起来像是一个数组)。

将声明更改为此(将assign更改为copy):

@property (nonatomic, copy) NSString *itemtitle;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *itemsubtitle;


您稍后将遇到的另一个不相关的问题是注释视图的重用:
现在,在viewForAnnotation 中,视图的image 仅在为某些注释“x”创建视图时(当annotationView == nil)设置。

但是,如果视图被重新用于另一个注释“y”,image 仍将设置为最初为注释“x”创建视图时的那个。

要解决这个潜在问题,请将 image 赋值移动到 if-else 块之后

    //Don't assign the image here
    //(because it's specific to the current annotation)
    //annotationView.image = [UIImage imageNamed:((MapItem *)annotation).icon];
} else {
    annotationView.annotation = annotation;
}

//Assign the image here...
//(because it's specific to the current annotation)
annotationView.image = [UIImage imageNamed:((MapItem *)annotation).icon];

return annotationView;

【讨论】:

    【解决方案2】:

    我在这个应用程序上使用了自定义注释,它应该是一个很好的例子。

    Green Up Vermont App - MapViewController

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 2015-02-15
      • 1970-01-01
      • 2013-07-20
      相关资源
      最近更新 更多