MKMapView removeAnnotations导致内存泄漏

时间:2011-01-31 02:01:35

标签: iphone memory-leaks annotations mkmapview

大家好! 我已经测试了这个最简单的代码如下:

StorePin.h

#import <Foundation/Foundation.h>  
#import <MAPKIT/mapkit.h>   
#import <CORELOCATION/corelocation.h> 


@interface StorePin : NSObject <MKAnnotation> {   

    CLLocationCoordinate2D coordinate;
    NSString *subtitle;   
    NSString *title;   
}   

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

-(id) initWithCoords:(CLLocationCoordinate2D) coords;   

@end

StorePin.m

#import "StorePin.h"


@implementation StorePin

@synthesize coordinate, subtitle, title;   

- (id) initWithCoords:(CLLocationCoordinate2D) coords{   

    self = [super init];   

    if (self != nil) {   

        coordinate = coords;    

    }   

    return self;   

}   

- (void) dealloc
{   
    [title release];   
    [subtitle release];   
    [super dealloc];   
}   

@end 

在我的ViewControlller中,我创建了一个按钮,可以重复添加和删除注释。

#import "mapViewTestViewController.h"
#import "StorePin.h"

@implementation mapViewTestViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}


- (IBAction)refresh
{
    [mapView removeAnnotations:mapView.annotations];

    for (int i = 0; i < 101; i ++)
    {
        CLLocationCoordinate2D p1;

        p1.latitude = i/10.0;   
        p1.longitude = i/10.0;  

        StorePin *poi = [[StorePin alloc] initWithCoords:p1]; 
        [mapView addAnnotation:poi];

        [poi release]; 
    }
}


- (void)dealloc
{
    [super dealloc];
}

@end

如果我循环少于100次来添加和删除注释,那么一切正常。但如果我循环超过100次,它将导致内存泄漏一次。我对这个奇怪的问题几近疯了。这是我的代码错误还是mkmapview的错误?谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您没有说出哪些对象被检测为泄漏,但如果它们是StorePin,那么它就是MapKit的问题 - 您在循环中创建的StorePin的内存管理代码很好。

可能导致MapKit问题的一件事就是将地图视图传递给你想要修改它自己的ivar的引用。它似乎不太可能 - 如果它真的是一个问题,它可能会导致崩溃而不是泄漏。但是,您可能会尝试制作副本,或者是浅层(正如Kai先前写的那样,但绝对 而不是遵循有关使用保留计数和调用release的建议循环):

NSArray * annotationsCopy = [NSArray arrayWithArray:mapView.annotations];

或深:

NSArray * annotationsDeepCopy = [[[NSArray alloc] initWithArray:mapView.annotations 
                                                      copyItems:YES] 
                                            autorelease];

然后将副本传递给removeAnnotations:

第二个选项创建一个自动释放的数组,其中包含注释列表中每个项目的副本,以便地图视图不会尝试删除它正在迭代的相同实例。显然这会占用两倍的内存;你可能只想为这个寻找漏洞而烦恼。

如果它修复了泄漏,那么很好,如果没有,那么你可能无能为力。

答案 1 :(得分:0)

如果您不想删除地图上用户的位置蓝点,您可以使用:

 NSArray * annotationsCopy = [NSArray arrayWithArray:[mapView.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"!(self isKindOfClass: %@)", [MKUserLocation class]]]];