需求
公司的內網測試環境因為網絡做過了限制,比較卡,所以測試連續點擊button
或者cell
時可能會多次push
控制器.如何在代碼改動范圍最小的范圍內來解決這個問題呢?
方法一(不推薦)
使用分類+運行時
來替換Button
的點擊方法,可以設置一個時間間隔
,點擊過后開啟一個計時器,并關閉按鈕的enable
屬性,計時完成后再打開enable
.至于cell
暫時沒有什么好點子.
優點:
- 改動比較小
缺點:
- 首先他要啟動不少定時器
- 如果點擊完成后,快速返回則不能再次點擊!必須等計時器執行完畢
方法二(能解決問題,但不優雅)
一般我們的網絡請求框架都會封裝
兩到三層AFN
,通過大量的block進行嵌套來完成一系列的請求
工作.所以我們可以設置一個全局id
變量,用來記錄當前點擊的button
和cell
,在最底層的網絡請求開始時將這個按鈕/cell的enable
關閉,成功后再次打開.
優點:
- 能解決問題
缺點:
- 記錄cell點擊,改動也不小
- 并發的問題
- 項目架構可能也有不適用的地方
方法三(推薦)
我們可以控制UINavigationController
中的push
方法,代碼很簡單,只需要判斷當前的控制器和推入的控制器是否是相同的
一個class
就好了.但有一個缺點,若本來就想push
一個相同的控制器就很尷尬了.代碼如下:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//cell因為網絡請求延遲而多次push同一頁面
if (![[super topViewController] isKindOfClass:[viewController class]]) { // 如果和上一個控制器一樣,隔絕此操作
[super pushViewController:viewController animated:animated];
}
}
方法四(強烈推薦)
鏈接,這位前輩的方式很巧妙,也解決了我上面的缺點
.
override func performSegueWithIdentifier(identifier: String, sender: AnyObject?) {
if let navigationController = navigationController {
guard navigationController.topViewController == self else {
return
}
}
super.performSegueWithIdentifier(identifier, sender: sender)
}