2013-05-07 93 views
9

我有一个自定义UIView调用ActivityDetailView,我实例化,然后添加到父视图控制器内的滚动视图。分配此自定义视图时,每增加一次内存就会占用大约1mb的时间,并且Instruments显示内存永远不会被释放,即使视图和父视图控制器各自都调用了它们的dealloc方法。我收到内存警告,应用程序最终被杀死,所以我显然做错了什么。内存不被释放MKMapView w/ARC

更新W绕地图视图是事业/信息,但我需要一个修复

在自定义ActivityDetailView笔尖文件,则存在被放大和周围的用户的位置为中心的地图视图。当我从笔尖移除该地图视图时,它不会在屏幕上绘图,内存分配问题就会消失。不过,我显然需要地图视图。为什么当地图视图超出范围时地图视图的数据不会被释放?

当视图显示时,只有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"); 
} 

在父视图控制器:

@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 screenshot

我没有任何东西g暂时缓存。该视图基本上是一个滚动视图,其中包含一个mapview,一些标签和一些表视图。表视图没有填充任何东西,我不在视图内加载任何图像,除了滚动视图的背景图像以外,但是当视图发生时,它应该被释放。

+1

不知道这是否是问题(也不应该是)。但是这两行代码是错误的detailView = nil; [detailView removeFromSuperview] ;.您应该调用removeFromSuperView,然后将其设置为nil。 – Cosmin 2013-05-07 13:23:17

+0

@Cosmin我认为没关系,如果它仍然被添加到另一个视图中,它不会达到dealloc ...我猜我们的OP只是在尝试一些东西,并将它留下。 – 2013-05-07 13:27:40

+0

@Cosmin As Grady说,我只是在尝试任何事情,看看它是否有所作为,但事实并非如此。 – ZeNewb 2013-05-07 13:31:30

回答

22

事实证明,iOS 6和MKMapView存在已知的错误,无法正确释放其内存。不幸的是,除了试图强制地图视图清除缓存,这对释放内存没有太大的影响。

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

最近苹果一直在测试中很sl sl。这是我遇到的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的一个实例,应该有助于减少每次多少内存分配的观点因为地图视图已经被分配了。

+0

伟大的建议,重新:使用MKMapView的一个实例,而不是每次alloc/dealloc'ing新的。我遇到了类似的问题......我们知道这个错误是否已从iOS 9+中解决? – 2016-08-26 14:49:54

+1

@ AdamW.Dennis我几年前还没有在Apple地图上工作过,所以您可能想要查看OpenRadar或Apple开发论坛以查看是否可以找到更多信息,例如https://openradar.appspot.com/search?query=mkmapview+memory – iwasrobbed 2016-08-26 15:17:21

0

这不是从您的笔尖文件创建自定义视图的最佳方式。我建议你做的是将你从.nib文件作为subview的视图添加到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; 
} 
+0

不幸的是,这对内存分配没有任何影响。 – ZeNewb 2013-05-07 13:35:05

+0

但你应该考虑他在说什么,总是会受到帮助表示赞赏 – 2013-09-25 22:40:39

0

您可能会遇到缓存问题。

如果您使用的图像很多,也许一个好的选择是从xib中删除这些图像,并使用代码添加它。或者,如果您使用[UIImage imageNamed:@""]

加载图像,但使用这样的事情:

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

为了更好的帮助,我需要知道如何开始你的表,还有其他功能。

+0

我目前没有任何东西需要缓存。该视图基本上是一个scrollview,里面有一个mapview和一些标签。表视图没有填充任何东西,我不在视图内加载任何图像,除了滚动视图的背景图像以外,但是当视图发生时,它应该被释放。 – ZeNewb 2013-05-07 15:04:31

+0

Nop,您在视图中添加的图像,使用imagenamed或从xib缓存,有时会导致应用程序崩溃。 – ggrana 2013-05-07 15:05:59

+0

背景图像被添加到笔尖中,并且与应用程序的其余部分使用的背景图像相同,所以我不认为这是问题。没有其他观点有分配问题,只有这个。 – ZeNewb 2013-05-07 15:07:14