MKMapView在超级视图被取消分配后仍然向委托发送消息

XJo*_*nes 14 objective-c ios xcode4.2 automatic-ref-counting

编辑:改变了标题.我当时不知道它,但这是一个重复的为什么我崩溃MKMapView释放后,如果我不再使用它?


这个问题类似于为什么在使用ARC + NSZombieEnabled时对象没有dealloc'ed,但足够不同以至于我认为值得抛弃,以防任何人理解并可以向我解释发生了什么.另一个问题可能是XCode错误,所以我认为这可能是类似的.

场景:

  1. RootViewControllertableView一堆显示项目
  2. 选择单元格会显示detailViewController包含另一个单元格的模态tableView
  3. 其中一个表格单元格detailViewController包含MKMapView显示项目的位置
  4. mapView.delegate = detailViewController
  5. 解散模态 detailViewController

在此之后不久,应用程序崩溃b/c MKMapView发送mapView:viewForAnnotation:到现在dealloc'ed detailViewController.此崩溃在具有临时分发构建的用户设备上重新编写,因此该问题与此无关NSZombieEnabled.

我能够通过添加以下内容来解决崩溃:

_mapView.delegate = nil;
Run Code Online (Sandbox Code Playgroud)

到包含mapView 的dealloc方法tableViewCell.

问题:为什么有必要在细胞被解除分配时使代表无效?mapView当细胞被解除分离时,似乎应该由ARC解除分离,这样就不必要了.没有代表是好的做法,但我认为在这种情况下不需要.

编辑:两者的所有子视图detailViewControllerUITableViewCells声明(nonatomic, strong)属性ala:

@property (nonatomic, strong)   MKMapView *         mapView;
Run Code Online (Sandbox Code Playgroud)

编辑2:猜猜我需要更好地阅读文档.@fluchtpunkt是对的.以下是MKMapView文档中的相关信息:

在释放已设置委托的MKMapView对象之前,请记住将该对象的委托属性设置为nil.您可以在dealloc方法中处理地图视图.

Mat*_*uch 19

MKMapView不是用ARC编译的,因为它的属性delegate仍被声明为assign而不是weak.
MKMapView文档:

@property(nonatomic, assign) id<MKMapViewDelegate> delegate
Run Code Online (Sandbox Code Playgroud)

过渡到ARC发行说明:

如果需要管理除释放实例变量之外的资源,则可以实现dealloc方法.您不必(实际上您不能)释放实例变量,但您可能需要在系统类和未使用ARC编译的其他代码上调用[systemClassInstance setDelegate:nil].


对于系统类(NS*,UI*)的委托,您必须在释放委托对象时使用将旧委托设置为nil的"旧"规则.

所以在你的detailViewController中添加一个dealloc方法

- (void)dealloc {
    self.mapView.delegate = nil;
}
Run Code Online (Sandbox Code Playgroud)