背景
本文是修復了UIControl和UITapGestureRecognizer沖突bug后,對UIButton的深入了解
Bug現(xiàn)場
在我的項目里有類似這樣一張視圖結(jié)構(gòu)的卡片
如圖所示:
- 藍色視圖上面添加了一個手勢
-
斧頭圖片的superView是藍色視圖,上面放了一個
UIButton - 下面黃色視圖和斧頭圖片平級,superView也是藍色視圖,上面放了一個
UIControl
故事情結(jié)
當我愉快的寫完這個UI,三下五除二的自測了一翻,嗯,很完美,提測。
周五晚上,我正準備下班的時候,測試同學忽然給我報了一個bug,右下角的UIControl跳轉(zhuǎn)邏輯,走到了下面手勢跳轉(zhuǎn)的邏輯
我心想這怎么會錯呢,我之前自測都是好的,再說右上角的跳轉(zhuǎn)都沒有問題
然后打開Xcode調(diào)試了一番,確實有問題
右上角UIButton跳轉(zhuǎn)是好的,UIButton繼承至UIControl,按道理他們的事件處理邏輯是一致的啊,但用UIControl自定的UI跳轉(zhuǎn)確實出了問題,
由于時間緊急,我也沒有深入研究,只能先修復再說
修復代碼
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return ![touch.view isKindOfClass:UIControl.class];
}
這段代碼邏輯很簡單,就不廢話了
Debug
在上線后,我一直在糾結(jié)這個點,就深入研究了一下,接下來探討一下為什么會導致這個Bug
一開始是往響應鏈條那方面想的,搞了這坨代碼測試
發(fā)現(xiàn)并不是什么響應鏈導致的
在網(wǎng)上搜了半天,也沒有搜出個什么結(jié)果,然后思考了半天,也沒有太好的思路,只好求助群友
忽然之前同事丟了這樣一張截圖
然后問他要了文檔鏈接,但是官方文檔似乎已經(jīng)更新了,我并沒有找到上面截圖的原文內(nèi)容,他給了我一篇博客的鏈接
有了這個思路,那我就想著把UIButton所有方法都打上斷點,我單步調(diào)試一下,總能發(fā)現(xiàn)線索
給UIButton所有方法設(shè)置斷點命令
br set -r '\[UIButton .*\]$'
關(guān)于lldb調(diào)試命令的我不贅述了,后面貼出lldb調(diào)試學習鏈接
得到了如下結(jié)果
UIButton部分方法
這里由于UIButton所有方法實在太多了(總共311個),沒辦法全部截圖,我只截取了其中導致這個bug的關(guān)鍵方法,見圖片高亮方法
給UIControl所有方法設(shè)置斷點命令
br set -r '\[UIControl .*\]$'
UIControl全部方法
這兩張圖可以很清楚的看到,UIControl中沒有這個方法[UIButton gestureRecognizerShouldBegin:]
那估計就是它了,隨后我又給這個方法下了一個斷點
br set -F "-[UIButton gestureRecognizerShouldBegin:]"
得到了這樣的結(jié)果
可以清楚的看到[UIGestureRecognizer _shouldBegin]里面調(diào)用了[UIButton gestureRecognizerShouldBegin:]
然后再請看
到這里,整個bug導致的原因已經(jīng)很清晰了
主要原因就是UIButton中的這個方法[UIButton gestureRecognizerShouldBegin:]
通過這次bug,也更新了自己對UIButton和UIControl的認知