0

我目前正在尝试修复我的应用程序中的内存泄漏(它没有使用泄漏工具显示),所以我正在使用 Allocations 工具的 heapshot 功能。我已经拍摄了几个 heapshots,如下所示:

快照

我正在执行的操作是从普通菜单更改视图-> 包含 MKMapView(带有叠加层)的视图并再次返回。

我检查过,每次进入 MKMapView 时内存都在增加。我在初始化时声明了一次 MKMapView,并且包含 MKMapView 的视图在应用程序周期结束之前永远不会被释放。所以这不应该是一个创作问题。

如果我进入其中一个堆,我可以看到以下内容:

分解的 heapshots

每个内存地址如下所示:

内存地址

我似乎无法弄清楚为什么会留下这么多 ​​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 回答