iPhone Bug分析過程和Xcode編譯器改進
iPhone Bug分析過程和Xcode編譯器改進是本文要介紹的內容,最近IPhone項目中的一個bug困擾了我兩天多,我把解決的過程分享出來,便于我自己整理思考問題的方式,也希望其中一些problem solving的方法能夠對大家有所借鑒。
現象:
在程序前后導航時,上一個頁面的導航欄會殘留,點擊其button會響應上一個頁面的事件或Crash。
這是在我剛剛Update到ios sdk 4.01時產生的,并且只在IPhone 2G 上重現,在模擬器和3GS上都正常工作。 我的直接想法就是,這是IPhone sdk的問題,因為新版本的sdk對2G不兼容導致的。但后來在Hailiang的IPod touch 3G上也能重現,我意識到這個bug的優先級比較高,需要解決。
首先,從現象入手,精確還原重現的條件。
IPhone 2G 3.1.2 重現
IPhone 2G 3.1.3 重現
IPod Touch 3.1.2 重現
IPhone 3Gs 3.1.3 不重現
IPhone 4G 4.1 不重現
IPhone simulator 不重現
分析:
從現象上分析,跟OS無關,因為在3.1.2 , 3.1.3上都能重現,還是跟硬件相關,在2G和ipod上重現,直覺還是新版SDK跟舊版硬件不兼容導致的,跟程序代碼無關。
那我就來驗證一下是否有這個兼容性問題,拿新版的SDK寫一個最簡單的sample導航程序在2G上跑,看能否重現。 結果是不能重現。 這說明之前的猜想不對,沒有兼容性問題,問題還是在我們的項目中。
那是什么問題呢? 代碼邏輯的問題嗎?但是在3GS上是工作的,應該不是代碼邏輯的問題。為了能把代碼邏輯問題獨立出來,我修改了項目的main函數,不執行我們的程序入口,而只是簡單創建兩個導航頁面。問題仍然存在。看來代碼邏輯是沒有問題的。
那極有可能是項目編譯配置的問題,于是我把項目所有的配置跟sample程序一一比較,將所有的關于代碼生成/優化等設置得跟sample一樣, 結果bug仍然存在,看來跟項目配置無關。為了確認跟項目配置無關,我把項目中的所有文件刪除,只留那兩個簡單導航頁面,問題不重現。 看來這個猜想是正確的。
那是什么問題呢? 考慮到我們用了好幾個第三方的庫。我覺的可能是第三方的庫的編譯設置問題或者是第三方的庫用到了某些庫跟舊版本的系統sdk沖突。 于是我把第三方的庫一一剝離出來,結果仍然重現。 這里順便提一下一個比較好的實踐,如果用到了第三方的庫,***把用到的接口放到一個獨立的文件里,這樣你懷疑第三方的庫有問題時,可以做一個stub,去掉第三方庫,方便驗證你的猜想。
既然第三方的庫也沒有問題,那看來是我們自己代碼的問題了。 沒有什么太好的辦法,我只好把我們的代碼一個個文件從項目中剝離,驗證bug是否重現。運氣不太好,當我剝離到***兩個文件時,才確認bug是出在那兩個文件里。 這里也順便提一下,保證項目中文件結構和依賴層次的清晰是非常重要的。比如A依賴B,B依賴C,C又依賴A,那在剝離的時候就很難下手。
Bug的root cause:
***的bug出在Queue.h 和Queue.m中,這是我之前寫的一個通用的Queue類(Objective-c 不提供Queue和Stack)。在Objective-C 中有Category的概念,跟C#中的partial class 概念類似,就是一個類的定義可以在兩個文件中。這樣就可以已這種方式對已有的類進行擴展,比如添加你自己的方法。我的Queue類 就是在Array類的基礎上 加了pop和push兩個方法,悲劇的是,在UINavigationController(IPhone導航)的實現里,它內部是用一個stack來維護每個導航頁面,而這個stack的實現方式我猜跟我實現Queue一樣,也是擴展了Array類,它也取名叫pop和push,兩者發生沖突。 我把push跟pop改為 enqueue和dequeue,問題解決。
- @interface NSMutableArray (QueueAdditions)
- - (id)pop;
- - (void)push:(id)obj;
@end
結論:
不要輕易懷疑SDK或者編譯器。 對于一些莫名其妙的bug,起初懷疑時系統的問題,往往還是你自己代碼的問題。
大膽假設,小心求證。對于所有難解的bug,從現象出發,根據你的經驗假設問題的所在,然后一步步驗證,抽絲剝繭,***總能找出問題所在。
另外的一個結論是, Apple 應該對編譯器做改進,在Category(partial class)里對重名的symbol,應該在鏈接的時候報錯,否則在運行時是很難去定位bug的。
小結:iPhone Bug分析過程和Xcode編譯器改進的內容介紹完了,希望本文對你有所幫助!
本文來自:http://www.cnblogs.com/MobileDevelop/archive/2010/10/12/1848601.html