2011-08-18 60 views
0

我用下面的代碼,以使一個引腳註釋:MKAnnotationView:內存泄漏

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)   annotation 
{ 
    MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentloc"]; 
    annView.pinColor = MKPinAnnotationColorGreen; 
    annView.animatesDrop=TRUE; 
    annView.canShowCallout = YES; 
    annView.calloutOffset = CGPointMake(-5, 5); 

    return annView; 
} 

一切完美,但分析XCode中顯示了該代碼內存泄漏。事實上,我也看到它,因爲我分配了對象,然後沒有釋放它。 如何避免內存泄漏?

回答

3

你沒寫,但我認爲分析告訴你什麼是泄漏的位置:

MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] 
           initWithAnnotation:annotation 
            reuseIdentifier:@"currentloc"]; 

那是因爲你需要自動釋放項目:

MKPinAnnotationView *annView=[[[MKPinAnnotationView alloc] 
            initWithAnnotation:annotation 
            reuseIdentifier:@"currentloc"] autorelease]; 

UPDATE

而且你不重用創建的註釋,請嘗試這樣做:

MKPinAnnotationView *annView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"currentloc"]; 
if(annView == nil) 
    annView = annView=[[[MKPinAnnotationView alloc] 
         initWithAnnotation:annotation 
          reuseIdentifier:@"currentloc"] autorelease]; 
+0

非常感謝,它幫助。 – Mitry

+0

檢查我的更新,這將加速您的代碼並減少內存使用量,因爲您可以隨時創建新對象而不是已經創建的重用。 –

1

事實上,我也看到它因爲我分配的對象,然後沒有釋放它。

你是對的泄漏原因。如果你需要從一個方法中返回一個被分配的對象,那麼這個想法就是自動釋放這個對象。

- (MyClass *)getObject { 
    MyClass *obj = [[MyClass alloc] init]; 
    return [obj autorelease]; 
} 

然後,如果需要,您將在調用方中保留返回的對象。

或者以這樣的方式命名該方法,以清楚返回的對象需要在調用者中釋放。然後在調用者中釋放。

+0

你是什麼意思_或以這種方式命名該方法,以清楚返回的對象需要在調用者中釋放。然後在調用者中釋放。 和 ' - (MyClass *)getObject {MyClass * obj = [[MyClass alloc] init]; return [obj autorelease]; } ' and ' - (MyClass *)getObject MyClass * obj = [[[MyClass alloc] init] autorelease]; return obj; }'? – Mitry

+0

你的兩個例子都是一樣的。這裏沒有實際的區別。通過命名我的意思是遵循iOS中廣泛使用的約定,以便調用者知道它何時擁有返回的對象(因此需要釋放返回的對象)以及何時獲取自動釋放對象。檢查這個問題:http://stackoverflow.com/questions/3979945/question-about-naming-conventions-for-cocoa-objective-c-for-iphone-with-respect – taskinoor

+0

按照慣例,名稱mapView:viewForAnnotation:means它返回一個自動釋放對象,如果需要,調用者需要保留它。而像newMapView:viewForAnnotation這樣的名稱:意味着它會回退一個分配的對象,因此調用者需要釋放該對象。非常鼓勵您遵循命名約定。 – taskinoor