iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
自我挑戰組

IOS從零成長30天日記系列 第 28

IOS-App KVO(2)

  • 分享至 

  • xImage
  •  

Day28

1.KVO實現原理:

.當某個類的對象第一次被觀察時,系統就會在運行期動態地創建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法
.派生類在被重寫的setter方法中實現真正的通知機制,就如前面手動實現鍵值觀察那樣。這麼做是基於設置屬性會調用 setter方法,而通過重寫就獲得KVO需要的通知機制。當然前提是要通過遵循KVO的屬性設置方式來變更屬性值,如果僅是直接修改屬性對應的成員變量,是無法實現KVO的。
.同時派生類還重寫了class方法以“欺騙”外部調用者它就是起初的那個類。然後系統將這個對象的isa 指針指向這個新誕生的派生類,因此這個對象就成為該派生類的對象了,因而在該對像上對setter的調用就會調用重寫的setter,從而激活鍵值通知機制。此外,派生類還重寫了dealloc方法來釋放資源。

2.change參數
默認change參數會包含一個NSKeyValueChangeKindKey鍵值對,傳遞被監聽屬性的變化類型:

typedef NS_ENUM(NSUInteger, NSKeyValueChange) {
NSKeyValueChangeSetting = 1,
NSKeyValueChangeInsertion = 2,
NSKeyValueChangeRemoval = 3,
NSKeyValueChangeReplacement = 4,
};

NSKeyValueChangeSetting =屬性的值被重新設置;
NSKeyValueChangeInsertion、NSKeyValueChangeRemoval、NSKeyValueChangeReplacement =表示更改的是集合屬性,分別代表插入、刪除、替換操作。
如果NSKeyValueChangeKindKey參數是針對集合屬性的三個之一,change參數還會包含一個NSKeyValueChangeIndexesKey鍵值對,表示變化的index。
(chang字典裡,新值的key為“new”,舊值的key為“old”,變化類型的key為“kind”。)

3、自動通知和手動通知

由於KVO會自動通知觀察者(默認)。固取消自動通知的方法是實現下面的類方法,透過返回NO來取消自動通知。

+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key

系統也會單獨針對這個屬性自動生成相關的類方法,是否自動通知這個屬性被改變,也可以單獨重寫這個類方法:

//假如有一個屬性
@property (copy, nonatomic) NSString *str;
//則系統會自動生成關於這個屬性的類方法,是否自動通知
+ (BOOL)automaticallyNotifiesObserversOfTest;

針對非自動通知的屬性,可以分別在變化之前和之後手動調用如下方法(will在前,did在後)來手動通知觀察者:

- (will/did)ChangeValueForKey:
- (will/did)ChangeValueForKey:withSetMutation:usingObjects:
- (will/did)Change:valuesAtIndexes:forKey:

好處:可以靈活加上自己想要的判斷條件,事實上自動通知也是框架通過調用這些方法實現的。

4.觸發KVO的三種方式:

有訪問器方法,則運行時會在訪問器方法中調用will/didChangeValueForKey:方法;沒有訪問器方法,運行時 會在 setValue:forKey:方法中調用will/didChangeValueForKey:方法。
直接使用了訪問器方法(點語法),會在運行時重寫setter方法,調用will/didChangeValueForKey:方法;
顯示調用will/didChangeValueForKey:方法。


上一篇
IOS-App 基本MVVM(1)
下一篇
IOS-App KVO(1)
系列文
IOS從零成長30天日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言