编辑:更改了标题。我当时不知道,但这是 Why am I crashing after MKMapView is freed if I'm no longer using it? 的副本
这个问题类似于Why is object not dealloc'ed when using ARC + NSZombieEnabled但差异很大,我认为值得扔掉,以防万一有人理解并可以向我解释正在发生的事情。另一个问题可能是 XCode 错误,所以我认为这可能是类似的。
场景:
RootViewController
有一个tableView
显示一堆项目- 选择一个单元格会显示一个模态
detailViewController
,其中包含另一个tableView
detailViewController
中的一个表格单元格包含一个显示项目位置的MKMapView
mapView.delegate = detailViewController
- 关闭模态
detailViewController
此后不久,应用程序崩溃,因为 MKMapView
将 mapView:viewForAnnotation:
发送到现在解除分配的 detailViewController
。此崩溃在具有临时分发版本的用户设备上重现,因此该问题与 NSZombieEnabled
无关。
我能够通过添加来解决崩溃问题:
_mapView.delegate = nil;
到包含 mapView 的 tableViewCell
的 dealloc
方法。
问题:为什么在释放单元格时需要将委托(delegate)设为 nil?似乎 mapView
应该在单元格被解除分配时由 ARC 解除分配,这就没有必要了。没有代表是一种很好的做法,但我认为在这种情况下不需要这样做。
编辑:detailViewController
和 UITableViewCells
的所有 subview 都声明为 (nonatomic, strong)
属性:
@property (nonatomic, strong) MKMapView * mapView;
编辑 2:我想我需要更好地阅读文档。 @fluchtpunkt 是正确的。以下是 MKMapView
文档中的相关信息:
Before releasing an MKMapView object for which you have set a delegate, remember to set that object’s delegate property to nil. One place you can do this is in the dealloc method where you dispose of the map view.
最佳答案
MKMapView 没有用 ARC 编译,因此 delegate
的属性仍然声明为 assign
而不是 weak
。
来自MKMapView documentation :
@property(nonatomic, assign) id<MKMapViewDelegate> delegate
并且来自 Transitioning to ARC Release Notes :
You may implement a dealloc method if you need to manage resources other than releasing instance variables. You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil] on system classes and other code that isn’t compiled using ARC.
对于系统类(NS*、UI*)的委托(delegate),您必须在解除委托(delegate)对象时使用将委托(delegate)设置为 nil 的“旧”规则。
所以给你的 detailViewController 添加一个 dealloc 方法
- (void)dealloc {
self.mapView.delegate = nil;
}
关于objective-c - MKMapView 在它的 super View 被取消分配后仍然发送消息给委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8568966/