【问题标题】:MKMapView removeAnnotations cause memory leakMKMapView removeAnnotations 导致内存泄漏
【发布时间】:2011-01-31 02:01:34
【问题描述】:

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

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 

在我的 ViewController 中,我制作了一个按钮来重复添加和删除注释。

#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 的错误?谢谢你帮助我。

【问题讨论】:

    标签: iphone memory-leaks annotations mkmapview


    【解决方案1】:

    你没有说哪些对象被检测为泄漏,但如果它们是StorePins,那么这是 MapKit 的问题——你在循环中创建的 StorePins 的内存管理代码就可以了。

    可能导致 MapKit 出现问题的一件事是向地图视图传递对它自己的 ivar 的引用,您希望它对其进行修改。这似乎不太可能——如果它真的是一个问题,它可能会导致崩溃而不是泄漏。但是,您可以尝试制作一个浅拷贝(正如 Kai 之前所写,但绝对 遵循关于使用保留计数和在循环中调用 release 的建议):

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

    或深:

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

    然后将副本传递给removeAnnotations:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-06
        • 2014-06-07
        • 2013-11-20
        • 2011-10-28
        • 2016-01-18
        • 2012-12-13
        • 1970-01-01
        • 2011-01-08
        相关资源
        最近更新 更多