删除/添加注释到地图视图会导致内存泄漏

发布于 2024-12-17 07:17:56 字数 2904 浏览 0 评论 0原文

我一直在尝试消除地图视图中的内存泄漏。我正在使用自定义地图图钉类。 一切正常,但问题是 - 我需要过滤地图视图结果。当我删除所有地图视图注释并添加过滤结果时,性能工具发现泄漏。但在我使用的这个mapPin类中使用了自动释放,所以它们应该被释放,但它们没有。我做错了什么?

MapPin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKMapView.h>
#import <MapKit/MKAnnotation.h>

@interface MapPin : NSObject<MKAnnotation> {
    CLLocationCoordinate2D coordinate;
    NSString * picture;
    NSInteger tag_number;
}

@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;


- (id) initWithCoordinate:(CLLocationCoordinate2D) coord;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic num:(NSInteger) number;
- (void) setPic:(NSString *) picture;
- (NSString* ) getPic;

- (void) setNum:(NSInteger) tag_number;
- (NSInteger ) getNum;

@end

MapPin.m

#import "MapPin.h"


@implementation MapPin

@synthesize coordinate = _coordinate;
@synthesize title = _title;
@synthesize subtitle = _subtitle;


- (id) initWithCoordinate:(CLLocationCoordinate2D) coord
{
    return [self initWithCoordinate:coord title:@""];
}

- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title {
    return [self initWithCoordinate:coord title:title subtitle:@""];

}
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle {
    return [self initWithCoordinate:coord title:title subtitle:subtitle image:@""];}

- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic{
    MapPin * me = [[[MapPin alloc] init] autorelease];
    me.coordinate = coord;
    me.title = title;
    me.subtitle = subtitle;

    [me setPic:pic];

    return me;
}

- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic num:(NSInteger) number{
    MapPin * me = [[[MapPin alloc] init] autorelease];
    me.coordinate = coord;
    me.title = title;
    me.subtitle = subtitle;

    [me setPic:pic];
    [me setNum:number];
    return me;
}

- (void) setPic:(NSString*) pic {
    picture = pic;
}

- (NSString * ) getPic{
    return picture;
}

- (void) setNum:(NSInteger) number {
    tag_number = number;

}

- (NSInteger ) getNum{
    return tag_number;
}

@end

I've been trying to get rid of memory leaks in mapview. I am using custom map pin class.
Everything works, but problem is - I need to filter mapview results. when i remove all mapview annotations - and add filtered results - performance tool finds leaks. but in this mapPin class I am using are used autorelease, so they should be released, but they aren't. what am I doing wrong?

MapPin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKMapView.h>
#import <MapKit/MKAnnotation.h>

@interface MapPin : NSObject<MKAnnotation> {
    CLLocationCoordinate2D coordinate;
    NSString * picture;
    NSInteger tag_number;
}

@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;


- (id) initWithCoordinate:(CLLocationCoordinate2D) coord;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic;
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic num:(NSInteger) number;
- (void) setPic:(NSString *) picture;
- (NSString* ) getPic;

- (void) setNum:(NSInteger) tag_number;
- (NSInteger ) getNum;

@end

MapPin.m

#import "MapPin.h"


@implementation MapPin

@synthesize coordinate = _coordinate;
@synthesize title = _title;
@synthesize subtitle = _subtitle;


- (id) initWithCoordinate:(CLLocationCoordinate2D) coord
{
    return [self initWithCoordinate:coord title:@""];
}

- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title {
    return [self initWithCoordinate:coord title:title subtitle:@""];

}
- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle {
    return [self initWithCoordinate:coord title:title subtitle:subtitle image:@""];}

- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic{
    MapPin * me = [[[MapPin alloc] init] autorelease];
    me.coordinate = coord;
    me.title = title;
    me.subtitle = subtitle;

    [me setPic:pic];

    return me;
}

- (id) initWithCoordinate:(CLLocationCoordinate2D) coord title:(NSString *) title subtitle:(NSString *) subtitle image:(NSString *) pic num:(NSInteger) number{
    MapPin * me = [[[MapPin alloc] init] autorelease];
    me.coordinate = coord;
    me.title = title;
    me.subtitle = subtitle;

    [me setPic:pic];
    [me setNum:number];
    return me;
}

- (void) setPic:(NSString*) pic {
    picture = pic;
}

- (NSString * ) getPic{
    return picture;
}

- (void) setNum:(NSInteger) number {
    tag_number = number;

}

- (NSInteger ) getNum{
    return tag_number;
}

@end

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

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

发布评论

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

评论(2

赴月观长安 2024-12-24 07:17:56

我一直在使用由 Mayur Birari 创建的自定义地图图钉,我对其进行了一些调整,以支持自定义地图图钉图像和 ID。

CustomMapPin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface CustomMapPin : NSObject<MKAnnotation> {

    CLLocationCoordinate2D  coordinate;
    NSString*               title;
    NSString*               subtitle;

    NSString*               pic;
    NSInteger               tag_number;

}

@property (nonatomic, assign)   CLLocationCoordinate2D  coordinate;
@property (nonatomic, copy)     NSString*               title;
@property (nonatomic, copy)     NSString*               subtitle;
@property (nonatomic, copy)     NSString*               pic;
@property (nonatomic)           NSInteger               tag_number;


@end

CustomMapPin.m

#import "CustomMapPin.h"


@implementation CustomMapPin

@synthesize title;
@synthesize subtitle;
@synthesize coordinate;
@synthesize pic;
@synthesize tag_number;


- (void)dealloc 
{
    self.title = nil;
    self.pic = nil;
    self.subtitle = nil;
    [super dealloc];
}

@end

并在类中使用它,如下所示:

CLLocationCoordinate2D pinlocation;

在循环中设置所需的值并创建地图图钉:

pinlocation.latitude = ...;

pinlocation.longitude = ...;

NSInteger pinID = ....;


CustomMapPin* customMapPin=[[CustomMapPin alloc] init];

customMapPin.coordinate=(CLLocationCoordinate2D
    {pinlocation.latitude,pinlocation.longitude};

customMapPin.title=@"title";

customMapPin.subtitle=@"subtitle";

customMapPin.pic = @"customImageName";

customMapPin.tag_number = pinId;


[mapView addAnnotation:customMapPin];

自定义图像:

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
    if ([annotation isKindOfClass: [CustomMapPin class]]) 
    {
        CustomMapPin * a = annotation;

        [annView setImage:[UIImage imageNamed:a.pic]];
    }
}

在标注上获取引脚 ID:

- (void)mapView:(MKMapView *)mp annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    CustomMapPin * v = (CustomMapPin *) view.annotation;

   int tagNumber = v.tag_number;

   ....
}

最后 - 在我的项目中需要有过滤器按钮 - 所以我需要删除所有引脚,并添加所需的引脚。默认情况下调用mapview来删除所有造成内存泄漏的注释。因此,当我需要从注释中清除地图视图时,我调用此函数:

- (void)removeAnnotations
{
    NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:[mapView.annotations count]];

    for (id annotation in mapView.annotations)
    {
        if (annotation != mapView.userLocation)
        {
            [toRemove addObject:annotation];
        }
    }

    [mapView removeAnnotations:toRemove];

    for(int i = 0; i < [toRemove count]; i++)
    {
        CustomMapPin * a = [toRemove objectAtIndex:i];

        [a release];

        a = nil;
    }
}

希望这有帮助
快乐编码! :)

I have been using cutom map pin created by Mayur Birari, which i tweaked a little bit, to support custom map pin images and id's.

CustomMapPin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface CustomMapPin : NSObject<MKAnnotation> {

    CLLocationCoordinate2D  coordinate;
    NSString*               title;
    NSString*               subtitle;

    NSString*               pic;
    NSInteger               tag_number;

}

@property (nonatomic, assign)   CLLocationCoordinate2D  coordinate;
@property (nonatomic, copy)     NSString*               title;
@property (nonatomic, copy)     NSString*               subtitle;
@property (nonatomic, copy)     NSString*               pic;
@property (nonatomic)           NSInteger               tag_number;


@end

CustomMapPin.m

#import "CustomMapPin.h"


@implementation CustomMapPin

@synthesize title;
@synthesize subtitle;
@synthesize coordinate;
@synthesize pic;
@synthesize tag_number;


- (void)dealloc 
{
    self.title = nil;
    self.pic = nil;
    self.subtitle = nil;
    [super dealloc];
}

@end

and using it in class like this:

CLLocationCoordinate2D pinlocation;

in a loop I set up required values and create a map pin:

pinlocation.latitude = ...;

pinlocation.longitude = ...;

NSInteger pinID = ....;


CustomMapPin* customMapPin=[[CustomMapPin alloc] init];

customMapPin.coordinate=(CLLocationCoordinate2D
    {pinlocation.latitude,pinlocation.longitude};

customMapPin.title=@"title";

customMapPin.subtitle=@"subtitle";

customMapPin.pic = @"customImageName";

customMapPin.tag_number = pinId;


[mapView addAnnotation:customMapPin];

Setting up custom image:

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
    if ([annotation isKindOfClass: [CustomMapPin class]]) 
    {
        CustomMapPin * a = annotation;

        [annView setImage:[UIImage imageNamed:a.pic]];
    }
}

Getting pin id on callout:

- (void)mapView:(MKMapView *)mp annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    CustomMapPin * v = (CustomMapPin *) view.annotation;

   int tagNumber = v.tag_number;

   ....
}

and finally - in my project It was required to have filter buttons - so I needed to remove all pins, and add required. By default calling mapview to remove all annotations created memory leaks. So when I need to clear mapview from annotations, I call this function:

- (void)removeAnnotations
{
    NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:[mapView.annotations count]];

    for (id annotation in mapView.annotations)
    {
        if (annotation != mapView.userLocation)
        {
            [toRemove addObject:annotation];
        }
    }

    [mapView removeAnnotations:toRemove];

    for(int i = 0; i < [toRemove count]; i++)
    {
        CustomMapPin * a = [toRemove objectAtIndex:i];

        [a release];

        a = nil;
    }
}

Hope this helps
Happy coding! :)

瞎闹 2024-12-24 07:17:56

您只是缺少 dealloc 实现!

例如:

- (void)dealloc 
{
    [self.title release];

    self.title = nil;

    self.subtitle release];

    self.subtitle = nil;

    [super dealloc];
}

You were just missing dealloc implementation!

for example:

- (void)dealloc 
{
    [self.title release];

    self.title = nil;

    self.subtitle release];

    self.subtitle = nil;

    [super dealloc];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文