0

現在、アプリケーション内のメモリ リークを修正しようとしている (リーク ツールを使用しても表示されない) ため、Allocations インストゥルメントのヒープショット関数を使用しています。以下に示すように、いくつかのヒープショットを撮りました。

ヒープショット

私が実行しているアクションは、通常のメニューからビューを変更することです - > MKMapView (オーバーレイ付き) を含むものと再び元に戻します。

確認したところ、MKMapView に入るたびにメモリが増加しています。初期化時に一度 MKMapView を宣言すると、MKMapView を含むビューはアプリケーション サイクルが終了するまで解放されません。したがって、それは作成の問題ではないはずです。

ヒープショットの 1 つに入ると、次のように表示されます。

分解されたヒープショット

各メモリ アドレスは次のようになります。

メモリアドレス

ビューが表示されるたびに作成される理由は言うまでもなく、非常に多くの QuartzCore オーバーヘッドが残っている理由を理解できないようです。どのオブジェクトがこれを直接呼び出しているか、またはどのオブジェクトがそれを保持しているかを確認する方法があるかどうか、誰か教えてもらえますか? これにより、最終的にアプリがクラッシュするのに十分なメモリリークが発生していますが、修正できないようです。

編集:

さて、ここに私のコードの一部があります(これは大きなコードなので、選択的なビットを表示しようとします):

メニューの最初に、これはマップ ボタンが押されたときに呼び出されます。

[self presentModalViewController:[dictionaryViews objectForKey:kMapView] animated:NO];

次に、マップをロードします。呼び出されるコードは次のとおりです。

- (void)viewDidAppear:(BOOL)animated
{
    if (self.mkMapView)
    {
        [self changeMapOverlay:14];

    Singleton *singleton = [Singleton sharedSingleton];

    if ([singleton.storyLocation isEqualToString:kGunthorpe])
    {
        CustomAlertView *alert = [[CustomAlertView alloc] initWithTitle:@"Map" message:@"Once you are ready to visit your first location touch the green pin and press the play button. If you are walking the streets use the directions tab to guide you." delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
        [alert show];
        [alert release];

        //int i =0;
    }

    // Setup for 30 fps
    float fps = 1.0 / 30.0;
    self.timerMap = [NSTimer scheduledTimerWithTimeInterval:fps target:self selector:@selector(mapLoop) userInfo:nil repeats:YES];  
}
}

これにより、次の処理を行う changeOverlay 関数が呼び出されます。

if (!self.mkMapOverlay)
    {
        MapOverlay *mapOverlay = [[MapOverlay alloc] init];
        [self.mkMapView addOverlay:mapOverlay];
        self.mkMapOverlay = mapOverlay;
        [mapOverlay release];

        mkOverlayRect = MKMapRectMake([self.mkMapOverlayView.overlay boundingMapRect].origin.x, [self.mkMapOverlayView.overlay boundingMapRect].origin.y, [self.mkMapOverlayView.overlay boundingMapRect].size.width, [self.mkMapOverlayView.overlay boundingMapRect].size.height);
    }
    else 
    {
        [self.mkMapOverlayView setHidden:FALSE];
    }

これは、マップがオーバーレイをデフォルト ビューとして使用することを確認するために呼び出されます (ハイブリッドと通常に変更できます)。- 確認したところ、マップ タイプを変更したことがないため、mapOverlay は初めて呼び出されます。

マップを終了するには、マップ ピンの detailDisclosureButton をクリックする必要があります。これにより、次のコードが呼び出されます。

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//NSLog(@"Annotation view selected - Start");
MapAnnotation *annotation = (MapAnnotation *)view.annotation;
NSString *locationName = [[NSString alloc] initWithString:[NSString stringWithString:annotation.title]];

if ([annotation.title rangeOfString:@"."].location != NSNotFound) 
{
    NSRange range = [locationName rangeOfString:@". "];
    int test = range.location + range.length;

    NSString *locationName2 = [[NSString alloc] initWithString:[locationName substringFromIndex:test]];

    [[NSNotificationCenter defaultCenter] 
     postNotificationName:@"GotoLocation" 
     object:locationName2];

    [locationName2 release];
    locationName2 = nil;
}

[locationName release];
locationName = nil;

[mapView deselectAnnotation:annotation animated:NO];

[self dismissModalViewControllerAnimated:NO];
//NSLog(@"Annotation view selected - Finish");
}

上記のコードはどれでも説明できますが、基本的に注釈にはタイトルがあり、正しい場所に移動するには番号を削除する必要があります。

4

1 に答える 1

0

私は Mac でプログラミングしていませんが、これは非常に疑わしいです:

確認したところ、MKMapView に入るたびにメモリが増加しています。初期化時に一度 MKMapView を宣言すると、MKMapView を含むビューはアプリケーション サイクルが終了するまで解放されません。したがって、それは作成の問題ではないはずです。

毎回このオブジェクトを構築しているのではなく、プログラムが終了するときにのみ破棄していると本当に確信していますか? 古典的なオブジェクトの寿命の混乱のようです。

于 2012-06-29T13:56:18.527 に答える