日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios 中 KVO

發布時間:2023/12/18 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios 中 KVO 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

KVO(Key value observe)鍵值觀察,是ios中的一種核心的概念,簡單的理解為當某一個對象A(或者多個對象)要想監聽對象的B的一個或者多個屬性發生變化時,就是用這種機制。

  • ?KVO的優點?
  • ? ? ? ? 當某個對象有個屬性改變,KVO會自動的消息通知對方,這樣的架構有多種好處。首先開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送消息通知,這是KVO機制的最大優點,因為這個方案已經被明確定義,獲得框架級的支持,可以方便的采用,開發人員不需要添加任何代碼,不需要設計自己的開發者模型,直接就可以在工程里使用,其次KVO的架構非常強大,可以很容易的支持多個觀察者觀察同一個屬性,以及相關的值? ? ? ? ? ?

    ? ? ?2、缺點,實時監聽對象屬性值的改變,非常消耗系統的性能。

    ? ? ?KVO 的面試題。

    ? ? 1、NSNotification和KVO的區別和用法是什么?什么時候應該使用通知,什么時候應該使用KVO,它們的實現上有什么區別嗎?如果用protocol和delegate(或者delegate的Array)來實現類似的功能可能嗎?如果可能,會有什么潛在的問題?如果不能,為什么?

    ? ? 答:KVO只能監測屬性的變化,通過NSString類型的屬性名來實現。但是實現了自動監測,當屬性值變化時,會自動通知觀察者,不用再添加代碼了。

    ? ? ? ? ? NSNotification比較靈活,可以監測的內容較多,但是需要被觀察者手動發送通知,觀察者才能響應。

    ? ? ? ? ? protocol通過添加一個NSArray也能實現類似的功能,但是實現上需要自己處理delegate的添加與刪除,自己在屬性變化時手動通知,較繁瑣,易出錯

    通知機制簡介

    /**

    ?*? NSNotificationCenter 兩個對象之間傳遞消息,或者多個對象之間傳遞消息

    ?*? a 對象觸發了某個事件(a對象不能完成),需要b對象完成,a對象(void)postNotificationName:(NSString *)aName object:(id)anObject;

    ?*? postNotificationName 發送消息的名字

    ?*? object 發送給哪個對象

    ?*? - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject; 誰接收通知,接收到通知后實現的方法(SEL)aSelector?

    ?*? removeObserver移除通知

    ?*/

    ? ? 下面的KVO的Demo代碼:

    ?

    1 Person.h內容 2 3 #import <Foundation/Foundation.h> 4 5 @interface Person : NSObject 6 7 @property (nonatomic , copy) NSString *name; 8 @property (nonatomic , assign) int age; 9 10 //- (void)dogNameChange; 11 12 //- (void)dogAgeChange; 13 14 @end 15 16 17 Person.m文件內容 18 #import "Person.h" 19 20 @implementation Person 21 22 //監聽者實現方法 23 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 24 { 25 if ([keyPath isEqual:@"name"]) //dog的name屬性改變了 26 { 27 NSLog(@"Dog - name- change,old:%@ ,new:%@;context = %@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey],context); 28 29 } 30 31 if ([keyPath isEqual:@"age"]) //dog的age屬性改變了 32 { 33 NSLog(@"Dog - age - change,old:%@ ,new:%@;context = %@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey],context); 34 } 35 } 36 37 //- (NSString *)description 38 //{ 39 // return [NSString stringWithFormat:@"name - %@, age - %d",self.name,self.age]; 40 //} 41 // 42 // 43 //- (void)dogNameChange 44 //{ 45 // NSLog(@"dogNameChange"); 46 //// [self removeObserver:self forKeyPath:@"name"]; 47 //} 48 // 49 //- (void)dogAgeChange 50 //{ 51 // NSLog(@"dogAgeChange"); 52 //} 53 54 @end 55 56 Dog.h內容 57 58 #import <Foundation/Foundation.h> 59 60 @class Person; 61 @interface Dog : NSObject 62 63 64 @property (nonatomic , weak) Person *onwer; 65 @property (nonatomic , assign) NSInteger age; 66 @property (nonatomic , copy) NSString *name; 67 68 @end 69 70 Dog.m內容 71 72 #import "Dog.h" 73 74 @implementation Dog 75 76 77 @end 78 79 ViewController.m內容 80 81 #import "SDViewController.h" 82 #import "Person.h" 83 #import "Dog.h" 84 85 @implementation SDViewController 86 87 - (void)viewDidLoad 88 { 89 [super viewDidLoad]; 90 Person *p = [[Person alloc] init]; 91 p.name = @"張三"; 92 p.age = 18; 93 94 Dog *d = [[Dog alloc] init]; 95 d.age = 10; 96 d.name = @"老狗"; 97 98 //KVO演練 -- 監聽某個對象屬性的改變 99 [d addObserver:p forKeyPath:@"age" options:(0x01 | 0x02) context:@"helloage"]; 100 [d addObserver:p forKeyPath:@"name" options:(0x01 | 0x02) context:@"helloname"]; 101 102 //KVC賦值 103 [d setValue:@(28) forKeyPath:@"age"]; 104 [p setValue:@"李四" forKeyPath:@"name"]; 105 [p setValue:@(10) forKeyPath:@"age"]; 106 [d setValue:@"小狗狗" forKeyPath:@"name"]; 107 108 // [d removeObserver:p forKeyPath:@"name"]; //移除KVO 109 // [d removeObserver:p forKeyPath:@"age"]; //移除KVO 110 111 112 }

    ?

    ?

    ?

    KVO中的頭文件中重要的方法簡介

    /*由于接收器已經被注冊為在相對于物體的關鍵路徑價值的觀察者,被通知更改該值。 變更字典總是包含NSKeyValueChangeKindKey項,其值是一個NSNumber包裝的NSKeyValueChange(使用 - [NSNumber的unsignedIntegerValue])。 NSKeyValueChange的意義取決于什么樣的屬性和關鍵線路識別: - 對于任何類型的屬性(屬性,以一對一的關系,或有序或無序的一對多關系)NSKeyValueChangeSetting表示該觀察對象已經收到了-setValue:forKey:消息,或者說,鍵 - 值編碼兼容的設置方法密鑰已被調用,或者一個-willChangeValueForKey:/ - didChangeValueForKey:對以其他方式被調用。 - 對于_ordered_一對多的關系,NSKeyValueChangeInsertion,NSKeyValueChangeRemoval和NSKeyValueChangeReplacement表明,突變的消息已發送到由-mutableArrayValueForKey返回的數組:發送給對象的消息,或者發送到由-mutableOrderedSetValueForKey返回的有序集合:消息發送給對象,或者說,鍵值中的一個編碼標準的陣列或有序集合突變方法的關鍵已被調用,或者一個-willChange:valuesAtIndexes:forKey:/ - didChange:valuesAtIndexes:forKey:對有否則被調用。 - 對于_unordered_一對多的關系,NSKeyValueChangeInsertion,NSKeyValueChangeRemoval和NSKeyValueChangeReplacement(在Mac OS10.4中引入)表明,突變的消息已發送到由-mutableSetValueForKey返回的集合:發送給對象的消息,或那一個鍵 - 值編碼兼容的一套基因突變的方法對密鑰已被調用,或者一個 -willChangeValueForKey:withSetMutation:usingObjects:/-didChangeValueForKey:withSetMutation:usingObjects:對了,否則被調用。 對于任何形式的財產,變更字典有一個NSKeyValueChangeNewKey項,如果NSKeyValueObservingOptionNew在觀察者注冊時指定,這是正確的一種變化,這是不是事先通知。變更字典包含NSKeyValueChangeOldKey如果指定NSKeyValueObservingOptionOld,這是正確的一種變化。請參閱該NSKeyValueObserverNotification非正式協議的方法是什么這些條目的值可以是評論。 對于一個_ordered_一對多的關系,變更字典總是包含一個NSKeyValueChangeIndexesKey條目的值是包含插入,刪除或替換的對象的索引,除非該變化是NSKeyValueChangeSetting一個NSIndexSet。 如果NSKeyValueObservingOptionPrior(中的Mac OS10.5引入)指定在觀察者登記時間,而該通知是一個先前被發送到的變化,結果,變更字典包含NSKeyValueChangeNotificationIsPriorKey項,其值被一個NSNumber包裝紙是(用 - [NSNumber的boolValue])。 背景始終是在觀察者報名時間的推移,在同一個指針。*///監聽者實現方法 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
    //注冊觀察者 -- observer 誰在監聽, keyPath -- 監聽哪一個屬性值 options -- 新的值與舊的值 context -- 傳送給observer 的消息 - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
    //移除觀察者 - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context NS_AVAILABLE(10_7, 5_0); - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

      

    轉載于:https://www.cnblogs.com/ndyBlog/p/3955885.html

    總結

    以上是生活随笔為你收集整理的ios 中 KVO的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。