没有为带有ARC的MKMapView发布内存 [英] Memory not being released for MKMapView w/ ARC

查看:87
本文介绍了没有为带有ARC的MKMapView发布内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义 UIView ,名为 ActivityDetailView 我实例化然后添加到父视图控制器中的scrollview 。分配此自定义视图时,每次额外内存大约需要1mb,而且仪器显示内存永远不会被释放,即使视图和父视图控制器都有 dealloc 被调用的方法。我收到内存警告,应用程序最终被杀死所以我显然做错了。

I have a custom UIView called ActivityDetailView that I instantiate and then add to a scrollview within a parent view controller. When this custom view is allocated, it takes up about 1mb each time of additional memory and Instruments is showing that the memory is never being released even though the view and the parent view controller each have their dealloc methods being called. I am getting memory warnings and the app is eventually getting killed so I'm obviously doing something wrong.

更新了有关地图视图的信息,但我需要修复

在自定义 ActivityDetailView nib文件中,有一个地图视图缩放并以用户的位置为中心。当我从笔尖中删除此地图视图以使其不在屏幕上绘制时,内存分配问题就消失了。但是,我显然需要地图视图。当地图视图超出范围时,为什么地图视图的数据不会被释放?

Within the custom ActivityDetailView nib file, there is a map view that is zoomed and centered around the users's location. When I removed this map view from the nib so that it doesn't draw on screen, the memory allocation issues went away. However, I obviously need the map view. Why would the map view's data not be released when the map view goes out of scope?

只有1 ActivityDetailView 和1 ActivityDetailViewController 在视图显示时处于活动状态。一旦我将视图从堆栈中弹出,它们就不再存在了。即使通过仪器显示对象被杀死,内存如何保持增长也没有意义。如果取消分配父视图,为什么地图视图数据不会被释放?

There is only 1 ActivityDetailView and 1 ActivityDetailViewController alive when the view is showing. As soon as I pop the view off the stack, they are no longer living. Doesn't make sense how the memory keeps growing even though the objects are being killed as shown via Instruments. If the parent views are deallocated, why isn't the map view data being deallocated?

我做错了什么或应该检查什么?

What am I doing wrong or what should I check?

这是自定义视图:

@interface ActivityDetailView ()
{
    CLLocation *location;
    __weak id parentViewController;
    int scrollViewX;

    ImageUtility *imageUtility;
}
@end

@implementation ActivityDetailView

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        NSArray *xibViews = [[NSBundle mainBundle] loadNibNamed:@"ActivityDetailView" owner:nil options:nil];
        if ([xibViews count] < 1) return nil;
        ActivityDetailView * xibView = [xibViews objectAtIndex:0];
        [xibView setFrame:frame];
        self = xibView;
    }
    return self;
}

- (id)initWithLocation:(CLLocation *)loc parentController:(id)parent
{
    self = [self initWithFrame:CGRectMake(0, 0, 320, 1000)];
    if (self)
    {
        imageUtility = [ImageUtility sharedManager];

        location = loc;
        parentViewController = parent;
        scrollViewX = 0;

        [self centerMapForActivityLocation];
        [self addPhotoButtonWithImageNamed:@"addActivityPhoto.png" target:parentViewController selector:@selector(addPhotoToActivity:)];
    }
    return self;
}

- (void)dealloc
{
    NSLog(@"ActivityDetailView was dealloced");
}

在父视图控制器中:

@interface ActivityDetailViewController ()
{
    ActivityDetailView *detailView;
}
@end

@implementation ActivityDetailViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Some code left out for clarity

    [self setupView];
}

- (void)didReceiveMemoryWarning
{
    NSLog(@"Purging image cache");
    [[ImageUtility sharedManager] purgeCache];
}

- (void)dealloc
{
    // These essentially do nothing to help the problem
    detailView.mapView = nil;
    [detailView removeFromSuperview];
    detailView = nil;
    self.scrollView = nil;

    NSLog(@"ActivityDetailViewController was dealloced");
}

- (void)setupView
{    
    // Add the activity detail view to the scroll view
    detailView = [[ActivityDetailView alloc] initWithLocation:self.activityLocation parentController:self];
    [self.scrollView addSubview:detailView];
    self.scrollView.contentSize = detailView.frame.size;

    // Setup the map view
    detailView.mapView.delegate = self;
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    annotation.coordinate = self.activityLocation.coordinate;
    [detailView.mapView addAnnotation:annotation];
    if (self.activity.mapImageName) {
        detailView.mapView.scrollEnabled = YES;
        detailView.mapView.zoomEnabled = YES;
    } else {
        detailView.mapView.scrollEnabled = NO;
        detailView.mapView.zoomEnabled = NO;
    }

    // Add the weather area to the view
    dayView = [[DailyButtonView alloc] initWithFrame:CGRectMake(0, -17, 60, 70)];
    dayView.hidden = YES;
    [detailView.weatherView addSubview:dayView];
}

这是来自Instruments的图片,显示大部分内存来自笔尖加载

Here's an image from Instruments showing that the majority of memory is from the nib loading

我目前没有任何要缓存的内容。视图基本上是一个scrollview,里面有mapview,还有一些标签和几个表视图。表视图没有填充任何内容,除了滚动视图的背景图像之外,我没有在视图中加载任何图像,但是当视图执行时它应该被释放。

I don't have anything to cache at the moment. The view is basically a scrollview with a mapview inside of it and some labels and a couple of table views. The table views aren't populated with anything and I'm not loading any images within the view other than the background image for the scrollview, but that should get released when the view does.

推荐答案

事实证明,iOS 6存在一个已知错误, MKMapView 没有正确释放内存。不幸的是,除了试图强制地图视图清除它的缓存之外没有真正的解决办法,这对释放内存没有那么大的影响。

As it turns out, there is a known bug with iOS 6 and MKMapView not releasing it's memory correctly. Unfortunately there is no real fix other than trying to force the map view to purge it's cache which doesn't have that great of an impact on releasing memory.

奇怪的是即使应用程序正在接收内存警告,地图视图缓存仍未正确清除。最终,该应用程序变得不稳定并被操作系统杀死。

The strange thing is that even when the app is receiving memory warnings, the map view cache is still not being purged properly. Eventually, the app becomes unstable and is killed by the OS.

Apple最近对他们的测试变得非常草率。这是我遇到的 MKMapView 的第二个错误(另一个是 mapViewDidFinishLoadingMap:被提前调用)和如果他们刚刚完成了一些性能和健全性测试,那么两个错误都很明显。

Apple has been getting very sloppy with their testing lately. This is the second bug with MKMapView that I've come across (the other being mapViewDidFinishLoadingMap: being called early) and both bugs have been really obvious to catch if they had just done some performance and sanity testing.

这里有一些代码可能有所帮助:

Here is some code which may help:

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    // This is for a bug in MKMapView for iOS6
    [self purgeMapMemory];
}

// This is for a bug in MKMapView for iOS6
// Try to purge some of the memory being allocated by the map
- (void)purgeMapMemory
{
    // Switching map types causes cache purging, so switch to a different map type
    detailView.mapView.mapType = MKMapTypeStandard;
    [detailView.mapView removeFromSuperview];
    detailView.mapView = nil;
}

你可以做的另一件事是使用<$ c $的一个实例c> MKMapView 在整个应用程序中,这应该有助于最小化每次显示视图时分配的内存量,因为已经分配了地图视图。

The other thing you could do is use one instance of the MKMapView throughout your entire app and that should help minimize how much memory is allocated each time the view is shown since the map view will already be allocated.

这篇关于没有为带有ARC的MKMapView发布内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆