今天修正了一个由于UIScrollView使用不当的导致的bug.
场景是这样的:
在一个视图里, 有滚动显示的图片. 图片是放在一个UIScrollView里的, 利用一个定时器, 每隔一定时间, 比如三秒, 调用UIScrollView的滚动方法, 定时器周期调用的方法如下:
-(void)dida {
[scrollView scrollRectToVisible:rect animated:YES]
}
进行滚动.
之后就发现, app在各个视图之间切换的时候, 会崩溃. 系统报EXEC_BAD_ACCESS, 开启僵尸对象之后(Enable Zombie Objects), 发现是上面的滚动视图代码访问了已经销毁的对象.
在对象的销毁方法里, 已经停止并删除了定时器, 怎么还会产生这种问题呢?
-(void)dealloc {
_timer.invalidate()
_timer=0
}
问题就出在animated这个参数上, 这个参数会让滚动变成一个持续一定时长的动画, 也就是说, 这个函数不会立即执行完毕, 而是会"飞"一段时间. 在飞的过程中, 对象销毁了, 但是方法还在持续修改视图的属性, 这就导致了crash.
所以在对象销毁的时候, 要让在”飞”的方法, 停下来. UIScrollView没有直接提供相关方法, 但是可以在销毁的时候, 非动画的滚动一次, 来停止可能存在的”飞”的滚动方法. 修改成下面代码后, 问题解决.
-(void)dealloc {
[scrollView scrollRectToVisible:rect animated:NO]
_timer.invalidate()
_timer=0
}