MapKit iOS8中的内存泄漏

Spa*_*son 5 memory-leaks objective-c mapkit ios ios8

我已经阅读了其他StackOverflow问题和解答,并了解这是自iOS6以来的一个错误(或者通过设计,必须解除分配代理,然后查看,谁知道).我不知道为什么或如何没有修复.

Anywho,我已经从其他答案添加了热门修补程序(下面,对于未来的读者):

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

- (void)applyMapViewMemoryHotFixOnDisappear{
    [self applyMapViewMemoryHotFix];
    self.mapView.showsUserLocation = NO;
    self.mapView.delegate = nil;
    self.locationManager.delegate = nil;
    [self.mapView removeFromSuperview];
    self.mapView = nil;
}

- (void)applyMapViewMemoryHotFix{
    switch (self.mapView.mapType) {
        case MKMapTypeHybrid:
        {
            self.mapView.mapType = MKMapTypeStandard;
        }

            break;
        case MKMapTypeStandard:
        {
            self.mapView.mapType = MKMapTypeHybrid;
        }

            break;
        default:
            break;
    }
    self.mapView.mapType = MKMapTypeStandard;
}

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    [self applyMapViewMemoryHotFix];
}
Run Code Online (Sandbox Code Playgroud)

但是,我的问题是,为什么内存不会降到MapKit级别之前?

MapKit之前/之后的内存使用情况

还有什么我想念的吗?这是预期的行为吗?分析器判断没有内存泄漏,但显然有些事情是不对的......

cou*_*rof 1

尽管 SO 社区使用了深受喜爱的 MemoryHotFix 来解决这个问题,但您应该确保您没有持有任何强引用。正如其他人所说,如果您使用(读取实例化)视图来保存对它们所在的视图控制器的引用,并且使用相同的视图控制器作为对该视图的引用,您可能会陷入强引用循环。

这种情况可能会阻止您的 deinit/dealloc 方法,从而使您的清理变得不必要且无用。

文档中所述:

您可以通过将类之间的某些关系定义为弱引用或无主引用而不是强引用来解决强引用循环。

所以一定要:

  1. 检查您的 deinit(swift)/dealloc 是否确实被调用(如果没有,则可能表明存在强引用循环)。
  2. 实际上,MKMapView 和 LocalitionManager 的委托以及它们本身为零。

像这样:

self.mapView.delegate = nil
self.mapView = nil
self.locationManager?.delegate = nil
self.locationManager = nil
Run Code Online (Sandbox Code Playgroud)

证明

考虑到这一点,下面是一个示例,其中一个 VC 用 MKMapView 推送另一个 VC,每条垂直红线表示“推送新 VC”,每条绿线表示“弹出它”:

在此输入图像描述

有一些初始设置(从 50 Mb +/- 开始),但未来的推送不会导致任何内存泄漏,如图所示。值得一提的是,这是使用真实设备拍摄的。我也使用模拟器对其进行了测试,尽管初始设置要高得多(从 100 Mb 开始),但结果是一致的。

希望你们能够解决这个问题,并且您也可以检查您的项目是否存在强引用循环,这可能会在未来损害您的产品;)