【问题标题】:MKMapView crashes app when view controller popped视图控制器弹出时,MKMapView 使应用程序崩溃
【发布时间】:2011-11-08 07:37:33
【问题描述】:

我有一个带有 MKMapView 的视图控制器,它调用

[self.mapView setRegion:region animated:YES]; 

将地图从 A 重新定位到 B。

持有 MKMapView 的视图控制器被设置为委托并在

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

我有一些代码会触发另一个 setRegion:animated: 到 MKMapView,以便地图会自动放大新位置。

如果我 popViewControllerAnimated 一切正常:MKMapView 动画完成平移和缩放后的视图控制器。

但是,当我尝试 popViewControllerAnimated: the current view controller WHILE MKMapView 正在运行它的动画时,应用程序崩溃并显示“发送到已释放实例的消息”。

从调试器的外观来看,我认为 MKMapView 正在尝试从弹出和解除分配的委托中调用方法。

所以我尝试了

[self.mapView setDelegate:nil];
self.mapView = nil;

在 viewDidUnload 中没有运气。该应用程序仍然经常崩溃。

我唯一能想到的就是创建一个单独的新委托类并从父视图控制器中保留该类,以便 MKMapView 即使在包含它的视图控制器被释放后也可以调用委托。

为什么会这样? 还有其他“干净”的选择吗?

【问题讨论】:

  • 这很有趣。当 MKMapView 调用委托以获取注释视图时发生的莫名其妙的崩溃使我们的应用程序瘫痪。问题是当时不存在 MKMapView;或者不应该。包含它的控制器早已被弹出。不知道是不是同样的问题。
  • 看起来和这个问题一样:stackoverflow.com/questions/2188098/…

标签: iphone objective-c ios mkmapview mkmapviewdelegate


【解决方案1】:

朋友帮我弄到了这个。

我实现了自己的弹出视图控制器的方法,而不是使用默认导航控制器的后退按钮。我只需要添加 [self.mapView setDelegate:nil];在我弹出视图控制器之前。

- (void)goBack
{
    [self.mapView setDelegate:nil];
    [self.navigationController popViewControllerAnimated:YES];
}

【讨论】:

  • 无法在 viewWillDisappear 中执行此操作?
  • @Oscar:我正要接受 Jiho 的回答,然后看到了你的建议。如果在 viewWillDisapear 中完成,应该可以工作。
【解决方案2】:

好的,这是真正的答案。它来自 Apple 文档,但 MKMapView 中缺少它。它只能在其委托协议的文档中找到:

“在释放您已为其设置委托的 MKMapView 对象之前,请记住将该对象的委托属性设置为 nil。您可以在其中处理地图视图的 dealloc 方法中执行此操作。”

注意:这也适用于 UIWebView。

我在委托的 dealloc 方法中将 MapView 的委托指针设置为 nil,我们的崩溃似乎已经消除。

【讨论】:

  • 这适用于任何对象,它的寿命可能比它的委托长。
【解决方案3】:

在我的视图控制器中将 MKMapView 的委托设置为 nil 并没有解决我的问题

[self.mapView setDelegate:nil];

我必须在我的 RootViewController 中对包含 MKMapView 的 UIViewController 进行 __strong 引用。

__strong *vcNewLocation;

【讨论】:

    【解决方案4】:

    我已经完成了聚类,并像 mapView.selectAnnotation(annotation, animated: true) 一样标记选择的注释。

    在弹出时,deinit 方法曾经崩溃。

    所以在按下后退按钮时,我只需添加这一行 mapView.deselectAnnotation(selectedAnnotation, animated: false) 即可解决崩溃问题。

    【讨论】:

      【解决方案5】:

      以下代码可能会解决您的问题:

      -(void) viewWillDisappear:(BOOL)animated
      {
          self.mapView.delegate = nil;
          mapView=Nil;
          NSLog(@"viewWillDisappear");
      
      }
      

      【讨论】:

      • 你忘了调用 viewWillDisappear:animated 的超级方法
      猜你喜欢
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-05
      相关资源
      最近更新 更多