国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

KVO -- 鍵值監(jiān)聽

2019-11-06 09:59:28
字體:
供稿:網(wǎng)友

1、KVO簡單介紹

KVO(Key Value Observing)鍵值監(jiān)聽,屬于蘋果官方API。

作用:iOS開發(fā)中通常將代碼分為數(shù)據(jù)模型和試圖控件,數(shù)據(jù)模型維護程序的狀態(tài)數(shù)據(jù),試圖控件將數(shù)據(jù)模型中的數(shù)據(jù)展示出來。而KVO能監(jiān)聽當(dāng)數(shù)據(jù)模型發(fā)生改變時,及時通知試圖控件動態(tài)將改變的數(shù)據(jù)顯示出來。 注意:只有通過setter方法改變的屬性值,才能被KVO監(jiān)聽到,才能觸發(fā)observeValueForKeyPath:ofObject:change:context:回調(diào)方法

KVO的使用: 1.注冊需要觀察的對象的屬性addObserver:forKeyPath:options:context: 2.實現(xiàn)observeValueForKeyPath:ofObject:change:context:方法,這個方法當(dāng)觀察的屬性變化時會自動調(diào)用 3.取消注冊觀察removeObserver:forKeyPath:context:

- (void)viewDidLoad { [super viewDidLoad]; self.stu = [[Student alloc] init]; // 添加觀察者 // observer:觀察者 keyPath:想要監(jiān)聽的屬性名 options:枚舉 回調(diào)時可以獲取改變前后的值 content:上下文 [self.stu addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];}// 屬性發(fā)生改變時的回調(diào)- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ // keyPath:屬性名 change:改變前后的屬性值 content:上下文 NSLog(@"%@", change[@"new"]);}// 釋放觀察者- (void)dealloc{ [self.stu removeObserver:self forKeyPath:@"age"];}

2、KVO底層實現(xiàn)(記錄自小馬哥視頻)

當(dāng)KVO被觸發(fā)時 1>首先系統(tǒng)會自動創(chuàng)建NSKVONotifying_Student類(這里以Student為例), NSKVONotifying_Student是Student的子類 2>修改當(dāng)前對象(student)的isa指針,指向NSKVONotifying_Student 3>只要調(diào)用對象的setter方法,就會調(diào)用NSKVONotifying_Student的setter方法 4>重寫NSKVONotifying_Student的setter方法:[super set:],通知觀察者對象的屬性值發(fā)生改變

下面我們來自己實現(xiàn)KVO,以便更好的理解KVO的底層實現(xiàn)過程。 1>系統(tǒng)KVO是基于NSObject,所以我們可以創(chuàng)建一個NSObject的分類NSObject+KVO NSObject+KVO.h文件

#import <Foundation/Foundation.h>@interface NSObject (KVO)- (void)zhaoName_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;@end

NSObject+KVO.m文件

#import "NSObject+KVO.h"#import <objc/runtime.h>#import "ZKVONotifying_Student.h"@implementation NSObject (KVO)- (void)zhaoName_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{ // 修改isa指針 本質(zhì)是改變當(dāng)前對象的類名 object_setClass(self, [ZKVONotifying_Student class]); // 保存觀察者 即動態(tài)添加屬性 // object:給哪個對象添加屬性 key:屬性名 value:屬性值 policy:關(guān)聯(lián)策略 objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end

2>重寫子類NSKVONotifying_Student的setter方法,通知觀察者 NSKVONotifying_Student.m文件

#import "ZKVONotifying_Student.h"#import <objc/runtime.h>@implementation ZKVONotifying_Student- (void)setAge:(NSUInteger)age{ [super setAge:age]; // 獲取保存的觀察者 id observer = objc_getAssociatedObject(self, @"observer"); // 通知 // 注意這里change傳nil,則在回調(diào)時change為空 [observer observeValueForKeyPath:@"age" ofObject:self change:nil context:nil];}@end

這樣調(diào)用我們自己實現(xiàn)的KVO也能實現(xiàn)屬性改變的監(jiān)聽

[self.stu zhaoName_addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 赫章县| 遂昌县| 虎林市| 峡江县| 大冶市| 藁城市| 滨州市| 泸州市| 武邑县| 浑源县| 巩义市| 寻乌县| 淮南市| 祥云县| 嘉黎县| 遂宁市| 闽侯县| 包头市| 西安市| 金乡县| 菏泽市| 大化| 溆浦县| 阿拉善盟| 义马市| 囊谦县| 苏尼特右旗| 虞城县| 孟津县| 连城县| 荥经县| 乌什县| 沧源| 澳门| 峨眉山市| 内黄县| 丹寨县| 兴山县| 松江区| 五峰| 呼玛县|