會記錄一些奇葩的閃退問題。
1.今日遇到一個閃退情況,在iOS8中UIScrollView在放大縮小的時候閃退。
前提:進入界面就會調用接口等接口回來后視圖放大功能,在放大動畫還沒有做的時候,返回到上一界面,然后再次進入當前的ViewController 閃退。
設備:6Plus
設備系統:iOS8 (其他系統調用沒有這個問題,可能iOS7 也存在當前這個問題。)
閃退的日志如下:
0 libobjc.A.dylib 0x000000019640bbd0 objc_msgSend + 16
1 UIKit 0x000000018a49b86c -[UIScrollView _getDelegateZoomView] + 76
2 UIKit 0x000000018a49b7ac -[UIScrollView _zoomScaleFromPresentationLayer:] + 32
3 UIKit 0x000000018a6af5c4 -[UIScrollView _zoomAnimationDidStop] + 96
4 UIKit 0x000000018a483c08 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 184
5 UIKit 0x000000018a483b10 -[UIViewAnimationState animationDidStop:finished:] + 100
6 QuartzCore 0x0000000189da8f60 CA::Layer::run_animation_callbacks(void*) + 292
7 libdispatch.dylib 0x0000000196a3d368 _dispatch_client_callout + 12
8 libdispatch.dylib 0x0000000196a4197c
根據閃退日志顯示,是UIScrollView 在做放大縮小的時候調用了 getDelegateZoomView (delegate 中的 viewForZoomingInScrollView )這個方法,然后開始調用objc_msgSend (消息傳遞 不懂的可以看下Runtime方面的知識)方法執行后出現閃退。
分析情況:如果調用方法的時候發現閃退,就是被調用的類沒有當前這個方法而閃退。 那么出現的情況是:1.當前的這個類已經被釋放,2.當前的這個類并沒有實現當前這個方法。
排除第2種猜測,原因是當前在使用正常的情況下是沒有問題的,當前的ViewController 也實現了 viewForZoomingInScrollView 這個方法。
所以是當前這個ViewController已經被釋放了,但是還是調用了delegate viewForZoomingInScrollView方法。
目前的情況是只出現在iOS8設備上,猜測iOS8 上ViewController釋放了但是UIScrollView delegate 沒有釋放。
修改方法:
1.在ViewController 釋放的時候 dealloc這個方法中,對 UIScrollView.delegate = nil;
- (void)dealloc{
_scrollView.delegate = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
為什么使用 _scrollView 呢?
當前的scrollView是懶加載的方式,如果在dealloc中調用 self.scrollView 會重新去調用ScrollView的生成 從而引發內存不釋放的問題。
思考: 拿到Crash日志,一看系統調用的時候掛了,就歸類到系統問題了,無法處理。有時候堅持一下,多看一會兒,多想一下,嘗試去Google上搜一下Crash信息中的一些字段,或許別人也有遇到過相同或者相似的問題,說不定得到啟發從而解決了一個看似沒法解決的問題。