没有为带有ARC的MKMapView发布内存

ZeN*_*ewb 9 memory mkmapview ios ios6

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

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

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

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

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

这是自定义视图:

@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");
}
Run Code Online (Sandbox Code Playgroud)

在父视图控制器中:

@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];
}
Run Code Online (Sandbox Code Playgroud)

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

仪器截图

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

iwa*_*bed 22

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

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

最近苹果公司的测试变得非常草率.这是MKMapView我遇到的第二个错误(另一个被mapViewDidFinishLoadingMap:称为早期错误),如果他们刚刚完成了一些性能和健全性测试,那么两个错误都非常明显.

以下是一些可能有用的代码:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

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