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

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

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

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

显示视图时,只有1个ActivityDetailView和1个ActivityDetailViewController处于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"); } 

在父视图控制器中:

 @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的图像,显​​示大部分内存来自笔尖加载

仪器截图

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

事实certificate,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; } 

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

这不是从nib文件创建自定义视图的最佳方法。 我建议你做的是将你从.nib文件中获取的视图作为子视图添加到self。 代码看起来应该是这样的。

 -(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 addSubview:xibView]; // This is where I have changed your code } return self; } 

您可能面临缓存问题。

如果您使用了大量图像,可能一个很好的选择是从xib中删除此图像并使用代码添加它。 或者,如果使用[UIImage imageNamed:@""]加载图像

但是使用类似的东西:

 NSData* dataImg = [NSData dataWithContentsOfFile:@"yourfile.png"]; UIImage* img = [UIImage imageWithData:dataImg]; 

为了更好地帮助我需要知道如何启动表格以及其他function。