MapKit自定义标注地图随机崩溃,Zombies提示MapView已释放
这种MapKit随机崩溃的问题我之前也碰到过几次,结合你给出的Zombies检测信息,核心原因就是MapView实例被释放后,仍然有代码尝试给它发送消息,下面给你几个具体的排查方向:
检查MapView的生命周期与持有关系
首先确认你的MapView是不是作为视图控制器的强属性存在?如果用了weak修饰或者被意外置为nil,很可能导致它提前被释放。另外,排查所有涉及MapView的闭包(比如网络请求回调、GCD异步任务):如果闭包捕获了MapView的强引用,可能造成循环引用;如果捕获的是弱引用,当MapView已经释放但闭包还在执行时,就会给僵尸对象发消息。排查自定义Annotation相关的回调逻辑
自定义标注的交互逻辑里很容易藏坑:- 你给AnnotationView的callout添加点击事件后,有没有在事件处理代码里直接引用MapView?
- 在
mapView:viewForAnnotation:这类代理方法中,返回的AnnotationView有没有持有MapView的引用?会不会导致释放时机混乱? - AnnotationView的复用、销毁逻辑里,有没有残留的定时器或异步操作还在指向MapView?
清理未移除的监听/定时器
如果你的MapView或所在VC注册了通知、KVO,或者添加了NSTimer,一定要在VC的dealloc或viewWillDisappear方法里及时移除这些监听。比如定时器如果没有调用invalidate,即使VC被销毁,定时器仍然会尝试触发目标对象的方法,若目标是已释放的MapView就会触发崩溃。用Instruments深入追踪消息来源
既然已经开启了Zombies检测,崩溃时可以查看完整调用栈,往上追溯调用respondsToSelector:的代码源头。比如是不是某个MapKit内部的异步更新回调,或者你自己的业务代码在VC被dismiss后,还在执行mapView.addAnnotation()这类操作?找到触发点就能精准定位问题。
内容的提问来源于stack exchange,提问作者surToTheW

