删除/添加注解MapView可以导致内存泄漏 [英] removing/adding annotations to mapview cause memory leaks

查看:120
本文介绍了删除/添加注解MapView可以导致内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图在图形页面摆脱内存泄漏。我使用的自定义地图销类。
一切正常,但问题是 - 我需要过滤的MapView结果。当我删除所有的MapView注释 - 并添加过滤的结果 - 性能工具发现泄漏。但在这个mapPin类我使用的用于自动释放,因此他们应该被释放,但事实并非如此。我究竟做错了什么?

MapPin.h

 #进口<基金会/ Foundation.h>
#进口< MapKit / MapKit.h>
#进口< MapKit / MKMapView.h>
#进口< MapKit / MKAnnotation.h>@interface MapPin:NSObject的< MKAnnotation> {
    CLLocationCoordinate2D协调;
    * NSString的图片;
    NSInteger的tag_number;
}@属性(非原子,分配)CLLocationCoordinate2D协调;
@属性(非原子,副本)的NSString *称号;
@属性(非原子,副本)的NSString *字幕;
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标;
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)称号;
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题字幕:(* NSString的)字幕;
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题字幕:(* NSString的)字幕图像:(* NSString的)图片;
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题字幕:(* NSString的)字幕图像:(* NSString的)PIC编号:(NSInteger的)的数量;
- (无效)setPic:(* NSString的)画面;
- (的NSString *)方法GetPic; - (无效)setNum:(NSInteger的)tag_number;
- (NSInteger的)getNum;@结束

MapPin.m

 #进口MapPin.h
@implementation MapPin@synthesize坐标= _coordinate;
@synthesize标题= _title;
@synthesize字幕= _subtitle;
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标
{
    返回[自我initWithCoordinate:坐标标题:@];
} - (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题{
    返回[自我initWithCoordinate:坐标标题:标题副标题:@];}
- (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题字幕:(* NSString的)字幕{
    返回[自我initWithCoordinate:坐标标题:标题字幕:字幕图片:@];} - (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题字幕:(* NSString的)字幕图像:(* NSString的)图片{
    MapPin *我= [[[MapPin页头] INIT]自动释放];
    me.coordinate =坐标;
    me.title =称号;
    me.subtitle =字幕;    [我setPic:PIC]    还给我;
} - (ID)initWithCoordinate:(CLLocationCoordinate2D)坐标标题:(* NSString的)标题字幕:(* NSString的)字幕图像:(* NSString的)PIC编号:(NSInteger的)数量{
    MapPin *我= [[[MapPin页头] INIT]自动释放];
    me.coordinate =坐标;
    me.title =称号;
    me.subtitle =字幕;    [我setPic:PIC]
    [我setNum:号];
    还给我;
} - (无效)setPic:(* NSString的)图片{
    照片=图片;
} - (的NSString *){方法GetPic
    返回的画面;
} - (无效)setNum:(NSInteger的)数量{
    tag_number =号;} - (NSInteger的)getNum {
    返回tag_number;
}@结束


解决方案

我一直用创建人对自定义地图销 MAYUR Birari,我调整了一点点,支持自定义地图销的图像和ID的。

CustomMapPin.h

 #进口<基金会/ Foundation.h>
#进口< MapKit / MapKit.h>@interface CustomMapPin:NSObject的< MKAnnotation> {    CLLocationCoordinate2D协调;
    * NSString的称号;
    * NSString的字幕;    * NSString的图片;
    NSInteger的tag_number;}@属性(非原子,分配)CLLocationCoordinate2D协调;
@属性(非原子,副本)的NSString *称号;
@属性(非原子,副本)的NSString *字幕;
@属性(非原子,副本)的NSString *图片;
@属性(非原子)NSInteger的tag_number;
@结束

CustomMapPin.m

 #进口CustomMapPin.h
@implementation CustomMapPin@synthesize称号;
@synthesize字幕;
@synthesize协调;
@synthesize图片;
@synthesize tag_number;
- (无效)的dealloc
{
    self.title =零;
    self.pic =零;
    self.subtitle =零;
    [超级的dealloc];
}@结束

和在课堂上使用它是这样的:

  CLLocationCoordinate2D pinlocation;

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

  pinlocation.latitude = ...;pinlocation.longitude = ...;NSInteger的pinID = ....;
CustomMapPin * customMapPin = [[CustomMapPin的alloc]初始化];customMapPin.coordinate =(CLLocationCoordinate2D
    {pinlocation.latitude,pinlocation.longitude};customMapPin.title = @称号;customMapPin.subtitle = @副标题;customMapPin.pic = @customImageNamecustomMapPin.tag_number = pinId;
[图形页面addAnnotation:customMapPin];

设置自定义图片:

   - (MKAnnotationView *)的MapView:(*的MKMapView)的MapView viewForAnnotation:(ID< MKAnnotation>)注释
{
    如果([注解isKindOfClass:[CustomMapPin类])
    {
        CustomMapPin * A =注释;        [annView setImage:[UIImage的imageNamed:a.pic]];
    }
}

上标注获取针ID:

   - (空)的MapView:(*的MKMapView),熔点annotationView:(MKAnnotationView *)查看calloutAccessoryControlTapped:(UIControl *)控制
{
    CustomMapPin * V =(CustomMapPin *)view.annotation;   INT tagNumber = v.tag_number;   ....
}

和最后 - 在我的项目它要求有过滤器按钮 - 所以我需要删除所有引脚,并添加所需的。默认情况下调用图形页面删除创建的内存泄漏的所有注释。所以,当我需要清除注释图形页面,我调用这个函数:

   - (无效)removeAnnotations
{
    NSMutableArray里*的文档,删除= [NSMutableArray的arrayWithCapacity:[mapView.annotations计数]];    对(在mapView.annotations ID注释)
    {
        如果(注释!= mapView.userLocation)
        {
            [文档,删除ADDOBJECT:注释]。
        }
    }    [图形页面removeAnnotations:文档,删除];    的for(int i = 0; I<文档,删除计数];我++)
    {
        CustomMapPin * A = [文档,删除objectAtIndex:i];        [释放];        A =零;
    }
}

希望这有助于
编程快乐! :)

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

解决方案

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! :)

这篇关于删除/添加注解MapView可以导致内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆