我司的App開始在iOS11上測試時,iOS11已經出到了bate6。在解決了一些常規的UI兼容問題后,一個詭異的bug引起了我的興趣。
情況是這樣的,在真機上先把App殺掉,然后啟動App,App打開,會顯示一個中間頁而非啟動頁,然后app會馬上被系統關閉,接著又被系統打開,出現正常的啟動頁面。整個過程行云流水,只有一個Bug干干凈凈的留給了我。
經過調試,發現中間錯誤的啟動和關閉都沒走到代碼中,只是看起來像那么回事,至少動畫是一樣的。
如果諸位已經在iOS11上跑app的話,極小可能已經復現這個Bug了。
我開始覺得這是一個系統級Bug,下一版自然會修復。結果Bate7果斷打臉,Bug依舊存在。
隨著上線日期的接近,我覺得把希望寄托于Apple顯然會引起滑鐵盧,畢竟iOS10.2AVPlayer的Bug至今還歷歷在目。沒辦法,只好上了。
抱著和“買一療程試試”同樣的覺悟,我開始了調試。結果很諷刺,第一次就猜出了問題的原因。
推理的過程比較有趣(此處腦補柯南經典BGM)。首先它會顯示一個中間頁,這個中間頁差不多是上次被殺掉時的頁面。有兩種可能:系統在App被殺掉后依舊保存一個頁面的截圖 或者 App沒有被正確的殺掉。前者不符合直觀邏輯,那就是后者。而App為什么沒有被正確的殺干凈?有兩種情況:所有的App都殺不掉,我司的App做了什么特殊操作造成殺不掉。試了幾個App,沒有該問題,那就是后者。那是什么代碼導致的呢?Table&Label之類的出問題必然不可能。難道是那些鉤子像赫魯曉夫一樣反水了嗎?當然不是。那是國內的幾個SDK的問題嗎?排查它們太麻煩。于是我退一步,按照樸素邏輯,應該是越靠近App被殺時的代碼越有可能引起問題。我找到了項目中最接近被殺時的方法applicationWillTerminate:。注掉了里面幾個觸發I/O的方法。問題居然就解決了。
記住,就是下面這個方法
applicationWillTerminate:
我新建了一個demo,在該方法中sleep了一下,果然Bug就復現了。
由于解決過程完全是黑盒操作,我無法解釋問題出現的原因,以及到底在該方法中寫什么代碼才會出現Bug。
只是希望Apple后續可以解決這個問題 :)