一句程式碼,更加優雅的呼叫KVO和通知

發表於2016-07-09

寫在前面

每次使用KVO和通知我就覺得是一件麻煩的事情,即便談不上麻煩,也可說是不方便吧,對於KVO,你需要註冊,然後實現監聽方法,最後還要移除,通知當然也需要移除操作,這使得相關邏輯的程式碼過於分散,控制器搞得亂亂的,而且總有時候會忘記移除什麼的,總之感覺不太好,所以我想如果能有方法新增一個KVO或者通知後能夠省略後面移除或者實現監聽方法步驟的話會多好,所以我就嘗試寫了一個分類,這個分類的目的在於儘可能簡化KVO和通知的步驟,對於KVO,你只需要一句程式碼就可完成監聽,無需自己手動移除,通知也差不多,介面如下:

使用也很簡單咯,github地址如下:XWEasyKVONotification,你只需要匯入NSObject+XWAdd這個分類,然後呼叫上面兩個介面即可完成KVO和通知,事例程式碼如下

是不是非常簡單,再也不用關心忘記移除導致的崩潰了,而且程式碼也集中,看著也更舒服了

原理

1、由於KVO和通知都差不多,原理部分通過KVO的介面的的實現原理進行說明,考慮到程式碼的統一我首先考慮到使用block,同時為了block能回撥,我們需要一個內部的物件target的來實現KVO的程式碼,在監聽到值改變的時候通過這個物件來回撥block,同時一個target應該對應一個keyPath,並且可應該對應多個Block,因為我們可能對一個keyPath進行多處監聽,這個類的具體程式碼大致如下:

2、實際進行KVO的監聽的物件有了,我們就可以開始書寫邏輯了,我們給每一個物件繫結一個targets的字典,每次呼叫該API註冊KVO的就去判斷有沒有對應的keyPath下的target(target和keyPath一一對應),沒有就建立,同時註冊這個keyPath的KVO,有就把block加入這個target以便回撥,具體程式碼如下:

3、上一段程式碼的最後一個方法是對dealloc方法進行調劑,因為我們想要能夠在合適的時候自動登出KVO,何為合適的地方呢,當然是被監聽物件銷燬的時候才是最合適的地方,所以dealloc方法裡面是最合適的地方,我們期望能交換被監聽物件的dealloc方法然後自己在該方法中實現登出KVO的邏輯,最先能想到的方式是通常我們使用的runtime中的swizzle黑魔法直接進行方法交換,但遺憾的是swizzle黑魔法只能在本類中交換本類的方法,而無法在一個類中對另一個類的方法進行調劑,所以需要另想調劑方法,我們採取直接對變監聽物件所在的類修改或者新增dealloc方法來達到調劑目的,我結合程式碼進行說明:

通過如上方式,我們就完成了對dealloc方法的調劑,新的dealloc方法執行的時候回登出註冊的KVO,這樣就免去了手動登出的麻煩事情咯!

寫在最後

通知的大致實現方式和KVO一樣,詳情請自行檢視程式碼咯,我就不多做說明了,現在終於能優雅愉快的使用KVO和通知了,複習一下github地址:XWEasyKVONotification 如果覺得對您有幫助,歡迎star!

相關文章