gpt4 book ai didi

ios - 没有为 MKMapView w/ARC 释放内存

转载 作者:IT王子 更新时间:2023-10-28 23:33:48 26 4
gpt4 key购买 nike

我有一个名为 ActivityDetailView 的自定义 UIView,我对其进行实例化,然后将其添加到父 View Controller 内的 ScrollView 中。当这个自定义 View 被分配时,每次额外的内存占用大约 1mb 并且 Instruments 显示内存永远不会被释放,即使 View 和父 View Controller 都有它们的 dealloc 方法叫。我收到内存警告,应用程序最终被杀死,所以我显然做错了什么。

更新了有关 map View 是原因的信息,但我需要修复

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

View 显示时只有 1 个 ActivityDetailView 和 1 个 ActivityDetailViewController 事件。一旦我从堆栈中弹出 View ,它们就不再存在了。即使通过 Instruments 显示对象被杀死,内存如何保持增长也没有意义。如果父 View 被释放,为什么 map View 数据没有被释放?

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

这是自定义 View :

@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");
}

在父 View Controller 中:

@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 的一张图片,显示大部分内存来自 nib 加载

Instruments screenshot

目前我没有要缓存的内容。该 View 基本上是一个 ScrollView ,其中包含一个 map View 以及一些标签和几个表格 View 。表格 View 没有填充任何内容,并且除了 ScrollView 的背景图像之外,我没有在 View 中加载任何图像,但是当 View 加载时应该会被释放。

最佳答案

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

奇怪的是,即使应用程序收到内存警告, map View 缓存仍然没有被正确清除。最终,应用程序变得不稳定并被操作系统杀死。

Apple 最近的测试变得非常草率。这是我遇到的 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;
}

您可以做的另一件事是在整个应用程序中使用 MKMapView 的一个实例,这应该有助于最大限度地减少每次显示 View 时分配的内存量,因为 map View 已经已分配。

关于ios - 没有为 MKMapView w/ARC 释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16420018/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com