我有一个导航控制器,其中VC1将VC2推送到导航堆栈中。 VC2在基于选项卡的视图中具有一个MKMapView,并且已打开用户位置。当我使用Heapshot Analysis工具检查仪器的重复分配时,当我回到VC1时,我反复发现某些MKUserLocation对象没有被释放。

我删除了所有注释,并在取消分配时也禁用了用户位置。堆增长的原因可能是什么?

将VC2推送到导航堆栈的VC1代码:

- (NSIndexPath *)tableView:(UITableView *)tableView
  willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    VC2 *vc2 = [[VC2 alloc] init];
    vc2.index = indexPath.row;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[self navigationController] pushViewController:vc2
                                           animated:YES];
    [vc2 release];
    vc2 = nil;
    return nil;
}

VC2中的dealloc代码:
- (void)dealloc {
//Other UILabel, UITextField objects dealloc methods go here
//The next four lines of code do not make a difference even if they are in viewWillDisappear
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView.layer removeAllAnimations];
self.mapView.showsUserLocation = NO;//This line does not make a difference in heapshot
mapView.delegate = nil;
[mapView release];
mapView = nil;
[super dealloc];

}

另外,如果不打开用户位置,则不会出现堆增长。

更新:我已经在模拟器和iPad 3G + WiFi上对此进行了测试,在这两种情况下,我都发现堆的增长。

最佳答案

如果要在IB中创建MKMapView,则应在 nil -viewDidUnload中发布/ -dealloc-将其发布。

否则,如果在视图控制器的生存期内卸载/重新加载了视图,则所有视图元素(无论如何都设置为保留属性)将在重新加载时泄漏。

在Web / SO上似乎有很多of不休,说这是5.0.1之前的API错误。您要针对哪个版本的SDK?

另外,请在黑暗中拍摄:仅尝试

self.mapView.showsUserLocation = NO;

要么
self.mapView.showsUserLocation = NO;
[self.mapView.layer removeAllAnimations];
[self.mapView removeAnnotations:self.mapView.annotations];

而不是您现在使用的这些命令的顺序。

可能是您在MKUserLocation有机会正确将其删除之前删除了MKMapView的注释?

10-07 19:51
查看更多