問題:在使用KVO的時候,如果在沒有添加監聽的情況下進行觀察者移除,會導致程序的崩潰.
這個問題看起來有點腦殘,如果沒有添加為什么還要移除, 但是我確實遇到了,它的情景是這樣的:
問題背景
如上圖:這是一個典型的以UITabBarController為根控制器的應用.
各個控制器的用途在圖中都有標出,其中在C控制器中,如果用戶點擊了
退出登錄
按鈕,我的處理方式是切換程序的根控制器(如果不是這樣的做法可能就不會有這個問題了).
問題來了,當我啟動app的時候,由于A是默認控制器, 就會首先執行A控制器的viewDidLoad:方法, 而B控制器的viewDidLoad:方法在我們點擊按鈕B的時候才會調用,B控制器才會添加對KVO的監聽.
當然,我們也可以通過其他方法使B的viewDidLoad:方法提前調用,但這不在我們這篇文章的討論范圍.
那么,如果app啟動后我沒有點擊B控制器而是直接進入C控制器并點擊了退出登錄, 這時進行了根控制器的切換,整個tabBarController都會被釋放,從而B控制器也就來到了dealloc方法(移除對KVO的監聽).這就是為什么,B控制器為什么會在沒有添加監聽的情況下就會被移除觀察者.
查了很久發現蘋果并沒有給我們提供一個判斷是否已經添加觀察者的方法,最后不得不采取了這個比較猥瑣的方法:
// 在B控制器中
- (void)dealloc {
@try {
[[ATBlueTooth shareInstance] removeObserver:self forKeyPath:@"isBluetoothConnecting"];
}
@catch (NSException *exception) {
}
}