objective-c - MKMapView 在它的 super View 被取消分配后仍然发送消息给委托(delegate)

标签 objective-c ios xcode4.2 automatic-ref-counting

编辑:更改了标题。我当时不知道,但这是 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 错误,所以我认为这可能是类似的。

场景:

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

此后不久,应用程序崩溃,因为 MKMapViewmapView:viewForAnnotation: 发送到现在解除分配的 detailViewController。此崩溃在具有临时分发版本的用户设备上重现,因此该问题与 NSZombieEnabled 无关。

我能够通过添加来解决崩溃问题:

_mapView.delegate = nil;

到包含 mapView 的 tableViewCelldealloc 方法。

问题:为什么在释放单元格时需要将委托(delegate)设为 nil?似乎 mapView 应该在单元格被解除分配时由 ARC 解除分配,这就没有必要了。没有代表是一种很好的做法,但我认为在这种情况下不需要这样做。

编辑:detailViewControllerUITableViewCells 的所有 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/

相关文章:

ios - 是否可以打开 Tweetbot 并分享图片?

objective-c - 在 Mac OS X 应用程序中拥有 DAL 和 BLL 层是否可行?

ios - 是否可以动态创建 swift 协议(protocol)的可选和非可选版本?

ios5 - IOS 5.0.1 与 XCode 4.2.1 说 "does not match any of the versions of iOS"

objective-c - 使用未声明的标识符 ' IKImageBrowserNSURLRepresentationType'

ios - NSString 到 NSUUID 转换

objective-c - Xcode 显示对焦环

ios - 解析 Swift : User relations with a "friends request"

ios - Swift:在应用程序之间共享身份验证状态

iOS symbolicate crash log 只符号化几行