系列:iOS開發(fā)-快速定位bug并解決
本來沒有打算針對(duì)這個(gè)開文的,
昨天工作忙完,閑來無事的時(shí)候,逛逛論壇,貼吧啥的,偶然間就發(fā)現(xiàn)了有人發(fā)bug帖.
http://www.reibang.com/p/b51ead39c55d
上面說的神乎其神呢...
大家可以去看看.
懷著好奇的態(tài)度,下載了源碼
干凈的很,任何代碼都沒有
只有sotryboard 拖拽了幾個(gè)控件, 綁定了present和dismiss的事件而已,除此以外沒有任何代碼
類似這樣
于是編譯運(yùn)行項(xiàng)目
按照他說的,確實(shí)出現(xiàn)了這個(gè)小而且偏的bug復(fù)現(xiàn)
于是想要解決bug
- 解決bug第一步
首先不管理內(nèi)存什么的問題,懷疑是不是vc沒有釋放?
于是在vc的dealloc中添加打印
-(void)dealloc{
NSLog(@"%s",__FUNCTION__);
}
運(yùn)行.返現(xiàn)沒有任何問題,vc能夠正常釋放,但是textField確實(shí)沒有被釋放.排除vc引用
-
解決bug第二步
關(guān)閉bug描述中所說的第一個(gè)關(guān)鍵條件
編譯運(yùn)行,發(fā)現(xiàn)bug已經(jīng)沒有復(fù)現(xiàn)了,項(xiàng)目運(yùn)行正常,vc能夠釋放,textField也能夠釋放.所以下定解決,出現(xiàn)bug的原因就是這個(gè)屬性了.
-
解決bug第三步
既然關(guān)閉了該屬性,就能解決bug,那么bug肯定是這個(gè)屬性導(dǎo)致的,
于是考慮能否使用手寫的方式.于是在vc中給這些小控件命名, 且手動(dòng)設(shè)置該屬性
編譯運(yùn)行,bug復(fù)現(xiàn),說明該屬性在iOS11下確實(shí)會(huì)強(qiáng)引用控件,導(dǎo)致不能釋放,
-
解決bug第四步
既然強(qiáng)引用導(dǎo)致的釋放問題,那么調(diào)整引用時(shí)機(jī)即可, 這里能想到的是使用弱指針,或者其他弱引用打破強(qiáng)引用即可
思路一,使用block來打破,這里因?yàn)閁ITextField沒有相關(guān)的block方法,添加方法也沒有什么意思,放棄
思路二,使用UITextField的代理,因?yàn)槭褂眠^代理的開發(fā)者都知道,其實(shí)weak屬性,所以其已經(jīng)打破了強(qiáng)引用的條件,我們只需在適當(dāng)?shù)拇矸椒ㄖ性O(shè)置即可
于是添加代理
代理完畢之后,找到合適的地方寫需要的代碼即可
遍歷代理方法,發(fā)現(xiàn)這三個(gè)方法應(yīng)該都是可以使用的,于是選擇第一條,在準(zhǔn)備編輯的時(shí)候便開始設(shè)置相關(guān)屬性,于一開始就設(shè)置應(yīng)該是一樣的效果,完全不影響之前的效果
于是添加代碼
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if (textField == self.psdTextField) {
textField.secureTextEntry = YES;
} else {
textField.secureTextEntry = NO;
}
return YES;
}
再次編譯運(yùn)行,
bug已經(jīng)不見了釋放問題得到解決.
- 解決bug第五步
為了防止會(huì)再次出現(xiàn)其他莫名bug,需要設(shè)置一些通用的設(shè)置,比如界面釋放結(jié)束編輯,vc釋放前釋放代理等
- (IBAction)back:(id)sender {
[self.view endEditing:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
所以整個(gè)bug修復(fù)的過程就是取消storyboard的secureTextEntry屬性,改為手動(dòng)添加,防止強(qiáng)引用,改為到代理里面設(shè)置,讓系統(tǒng)自動(dòng)幫我們打破強(qiáng)引用即可.
bug修復(fù)demo
https://github.com/spicyShrimp/iOS11_UITextField_Fix
其實(shí)這是一個(gè)很簡(jiǎn)單的bug修復(fù)問題
所以這個(gè)問題其實(shí)引出了我們作為iOS開發(fā)如何能快速定位bug的問題
在我們開發(fā)的時(shí)候,我們會(huì)經(jīng)常出現(xiàn)各種莫名的bug,而自己卻不能夠定位,找不到思路,其實(shí)對(duì)于bug定位這個(gè)是一個(gè)技巧和經(jīng)驗(yàn)的問題
大家都知道的方式有,打斷點(diǎn),逐行判斷,打印log,判斷是否正確輸出...
經(jīng)驗(yàn)在豐富一點(diǎn)的會(huì)使用控制臺(tái)來po一些屬性的值...
這些基本上每一個(gè)開發(fā)者都天天在用.
但是并不是這些就能完全的解決bug了
解決bug不是一味的出現(xiàn)bug,并且明確了bug發(fā)生的地方才能解決,很多bug是系統(tǒng)本事遺留導(dǎo)致
比如,我上篇博文說的文件索引在XCode9中的問題導(dǎo)致的bug就和代碼完全無關(guān)
比如,上面提到的bug,小而偏,完全無法定位bug出現(xiàn)在哪一行
比如,我昨晚幫網(wǎng)友解決的一個(gè)響應(yīng)鏈關(guān)系的bug,視圖層次都是正確的,但是就是沒有響應(yīng)事件,網(wǎng)友卻認(rèn)為是子控件本身的bug導(dǎo)致,卻沒有換個(gè)思路,想到關(guān)于圖層結(jié)構(gòu),是否可以響應(yīng)事件,等基本常見bug,(最終問題也是出在的這里,圖層window的問題,這里不贅述了)
所以這里我簡(jiǎn)單的總結(jié)一些解決bug的經(jīng)驗(yàn),分享給大家,希望大家都沒有bug,
-
多打印log----log能夠最簡(jiǎn)單直接的反應(yīng)很多東西,比如屬性的值,比如對(duì)象的類是否正確.....
-
多添加關(guān)鍵斷點(diǎn)----類似于log,我們每一個(gè)有問題的bug,大部分都是有復(fù)現(xiàn)路徑的,我們需要逐步分析這個(gè)復(fù)現(xiàn)路徑,就需要對(duì)每一個(gè)關(guān)鍵點(diǎn)添加斷點(diǎn),逐一排除即可修復(fù)
-
學(xué)會(huì)使用異常斷點(diǎn)等高級(jí)方式
當(dāng)我們無法明確某些復(fù)現(xiàn)路徑的時(shí)候,我們可以通過異常斷點(diǎn)來破獲問題出現(xiàn)的地方
關(guān)于使用方法,大家可以自行網(wǎng)上學(xué)習(xí)一下,即可
-
學(xué)會(huì)使用po命令---- 添加斷點(diǎn),出現(xiàn)異郴秸福或者中斷之后,對(duì)于沒有l(wèi)og的信息,我們可以使用po命令來獲取.
-
學(xué)會(huì)使用其他工具,工具很多,這里不做介紹,比如instrument等.這些工具的掌握對(duì)于解決bug是很有幫助的
- 使用crash日志---我們可以使用本地保存crash日志,也可以使用一些三方的bug收集SDK進(jìn)行接入,比如bugly等,其可以在一定程度上定位到bug出錯(cuò)的位置,幫助我們解決
- 分析bug出現(xiàn)關(guān)鍵因素,對(duì)于上述還是無法定位bug的,我們需要自行分析bug出現(xiàn)的關(guān)鍵因素,不要放過任何一個(gè)細(xì)節(jié),比如找不到某某方法,那就是要么沒有引用文件,要么沒有添加到項(xiàng)目,要么沒有實(shí)現(xiàn)方法,要么編譯器沒有找到索引路徑等.再比如上面的bug問題,關(guān)鍵點(diǎn)就是一個(gè)屬性導(dǎo)致,我們?cè)诙ㄎ籦ug初期就應(yīng)該能夠想到,但是很多人卻會(huì)忽略它
- 使用一些不同的思路去打破bug路徑,這個(gè)是經(jīng)驗(yàn)的問題,很多bug,使用普通的思路無法解決,可能是系統(tǒng)私有化,可能是時(shí)間拿不到,可能是其他一些因素?zé)o法控制,此時(shí)就需要經(jīng)驗(yàn)了,如何能夠改變思維,改變固有想法去繞過bug,也是需要掌握的,大家可以參考我的另一篇博客 ------( iOS11 導(dǎo)航欄按鈕位置問題的解決 http://blog.csdn.net/spicyShrimp/article/details/77891717)
對(duì)應(yīng)很多因?yàn)橄到y(tǒng)限制的原因,無法使用正常思維解決的,我們就要另辟蹊徑,至于如何做,這里只能說,熟能生巧 - 多積累基礎(chǔ)知識(shí),很多bug出現(xiàn)的因素并不是必然的,往往都是開發(fā)者的不嚴(yán)謹(jǐn)?shù)倪壿嬙斐傻?所以算法的優(yōu)劣,思路的清晰能夠幫助我們減少很多bug,但是bug出現(xiàn)也不要擔(dān)心,解決一次,就增長(zhǎng)了一份記錄,我們只要記錄下來,下次就會(huì)自行很快的解決了,學(xué)習(xí)的路徑有很多,論壇,書籍,視頻,交流等..我們都不應(yīng)該放過
- 對(duì)于每一個(gè)iOS或者Xcode的升級(jí)(其他開發(fā)工具或者開發(fā)環(huán)境也一樣),如果可以,盡早的去適應(yīng)和學(xué)習(xí)新的不同點(diǎn),及早的思考某些API的改變會(huì)對(duì)我們的開發(fā)造成什么影響,做到提早預(yù)防
其實(shí),能否對(duì)bug的快速定位,也間接反映了你的能力水平
希望大家在開發(fā)的時(shí)候永遠(yuǎn)沒有bug....
歡迎訪問我的系列博客
系列:iOS開發(fā)-前言+大綱
http://blog.csdn.net/spicyShrimp/article/details/62218521