开发者

MKMapView removeAnnotations cause memory leak

开发者 https://www.devze.com 2023-02-07 19:49 出处:网络
everyone! I have tested this simplest code as following: StorePin.h #import <Foundation/Foundation.h>

everyone! I have tested this simplest code as following:

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:(CLLocationCoordinate2开发者_开发知识库D) 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 

In my ViewControlller, I made a button to add and remove annotations repeatly.

#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

If I loop less than 100 times to add and remove annotations, all work normally. But if I loop more than 100 times, it will cause memory leak once. I'm nearly crazy to this strange problem. Is this my code's bug or mkmapview's bug? Thank you for helping me.


You don't say what objects have been detected as leaking, but if they are StorePins, then it's MapKit's problem -- your memory management code for the StorePins you create in the loop is just fine.

One thing that you do that might be causing MapKit trouble is passing the map view a reference to its own ivar that you want it to modify. It doesn't seem too likely -- if it was really a problem, it would probably cause a crash rather than a leak. However, you might try making a copy, either shallow (as Kai wrote earlier, but absolutely do not follow the advice about using retain counts and calling release in a loop):

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

or deep:

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

then pass the copy to removeAnnotations:.

The second option creates an autoreleased array with a copy of every item in the annotations list so that the map view doesn't try to remove the same instances that it's iterating over. Obviously this uses twice the memory; you probably only want to bother with this for bug-hunting.

If it fixes the leak, great, if not, then there's probably nothing you can do about it.


In case you don't want to remove the user's location blue dot on the map, you can use:

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

精彩评论

暂无评论...
验证码 换一张
取 消