2011-01-31 42 views
0

大家好! 我已經測試這個簡單的代碼如下:MKMapView removeAnnotations導致內存泄漏

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次,會造成一次內存泄漏。我對這個奇怪的問題幾乎感到瘋狂。這是我的代碼的bug或mkmapview的錯誤?感謝你們對我的幫助。

回答

1

你不會說什麼對象被檢測爲泄漏,但是如果它們是StorePin s,那麼它就是MapKit的問題 - 你在循環中創建的StorePin的內存管理代碼就很好。

你這樣做的一件事可能會導致MapKit的麻煩是將地圖視圖傳遞給它自己想要它修改的ivar的引用。這似乎不太可能 - 如果確實是一個問題,它可能會導致崩潰而不是泄漏。但是,你可能會嘗試進行復印,無論是淺(如凱之前寫的,但是絕對遵守有關使用保留計數和在循環中調用release建議):

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

或深:

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

然後將副本傳遞給removeAnnotations:

第二個選項創建一個autoreleased數組,其中包含註釋列表中每個項目的副本,以便地圖視圖不會嘗試刪除它正在迭代的相同實例。顯然這使用了兩倍的內存;你可能只想打擾這個尋找bug。

如果它修復了泄漏,那麼很好,如果沒有,那麼你可能無法做到這一點。

0

如果你不想刪除地圖上的用戶位置的藍色圓點,您可以使用:

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