【问题标题】:MKMapView dealloc'ed when calling addOverlay调用 addOverlay 时 MKMapView 已解除分配
【发布时间】:2014-02-22 16:48:42
【问题描述】:

当我在 - (void)viewDidLoad 中调用它时,我的 mapView 被释放时遇到问题

NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
self.onlineOverlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
self.onlineOverlay.canReplaceMapContent = YES;
[_mapView addOverlay:self.onlineOverlay level:MKOverlayLevelAboveLabels];

日志是:(启用了僵尸对象)

*** -[VKRasterOverlayTileSource invalidateRect:level:]: message sent to deallocated instance 0xf1863e0

只有当我过早关闭包含地图视图的视图控制器时才会发生这种情况。 如果我等待几秒钟,它不会崩溃。 视图控制器通过从导航控制器中弹出来解除,

我尝试了几种选择:

  1. mapView & mapView.delegate- (void) dealloc and in - (void)viewDidDisappear 中设置为nil
  2. BOOL finishedLoading 在视图加载时设置为 FALSE,在调用地图视图委托方法 - (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered 时设置为 TRUE
  3. - (void)mapView:(MKMapView *)mapView didAddOverlayRenderers:(NSArray *)renderers 似乎在方法完成之前被调用了。

如何检查叠加层是否已完全添加?

或者如果视图控制器被关闭,是否可以取消覆盖?

编辑: 视图控制器位于导航控制器堆栈中,并被呈现和弹出。 我自己没有使用任何线程。从仪器中我可以看到还有另一个线程,所以我的猜测是addOverlay: 正在某个地方创建一个线程。

mapView 是 viewController 的属性,也是委托。

【问题讨论】:

  • 应该没有“完全添加”这样的东西。在添加叠加层的时间与可以安全地关闭包含的视图控制器的时间之间存在延迟这一事实表明存在线程问题。请显示/描述您要在其中添加叠加层的整个代码/上下文。
  • 我添加了更多信息。我希望这就够了,谢谢。
  • 您必须有一个mapView:rendererForOverlay: 的实现。使用日志来查看是否在视图控制器被关闭后 调用它。如果是这样,如果地图不再存在,也许你应该返回 nil。
  • 我在弹出视图控制器之前设置了_mapView = nil。然后在mapView:rendererForOverlay: 检查零,但这没有帮助,它仍然崩溃。
  • 我害怕那个。 - 如果你在“VKRasterOverlayTileSource crash”上进行谷歌搜索,你会发现你并不孤单。但是,我没有找到明确的解决方案。问题显然是在您离开视图控制器并且所有内容都被释放后继续下载图块。但我不知道如何防止这种情况,因为下载是自动为你完成的。 :(

标签: ios mkmapview


【解决方案1】:

在 tileOverlay 子类中设置指向您的 mapView 的指针。这样,当调用结果块时,mapView 仍然存在。您必须在 tileOverlay 子类中手动添加 mapView 属性。

NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png"; self.onlineOverlay = [[MKTileOverlay alloc] initWithURLTemplate:template]; self.onlineOverlay.canReplaceMapContent = YES; self.onlineOverlay.mapView = _mapView; [_mapView addOverlay:self.onlineOverlay level:MKOverlayLevelAboveLabels];

【讨论】:

  • MKTileOverlay 没有 mapView 属性。
  • 是的,但是您可以像我上面所说的那样,向您的覆盖子类添加一个强大的 MKMapView 属性。您不需要使用该类,但强指针将使实例在结果块回调中保持活动状态。将此行添加到您的覆盖子类 @property (nonatomic, strong) MKMapView *mapView;
  • 啊抱歉,由于某种原因我没有赶上子类。我知道了,会试试看。
  • @anton Gregerson 如果这对您有用,请将其标记为正确答案以供其他人参考。
  • 这会导致内存泄漏,因为它会创建一个保留周期。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
相关资源
最近更新 更多