成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Objective-C KVO簡單探索

移動開發 iOS
KVO(Key Value Observing),是觀察者模式在Foundation中的實現。當一個object有觀察者時,動態創建這個object的類的子類,對于每個被觀察的property,重寫其set方法;當一個property沒有觀察者時,刪除重寫的方法,當沒有observer觀察任何一個property時,刪除動態創建的子類。

KVO(Key Value Observing),是觀察者模式在Foundation中的實現。

KVO的原理

簡而言之就是:

1、當一個object有觀察者時,動態創建這個object的類的子類

2、對于每個被觀察的property,重寫其set方法

3、在重寫的set方法中調用- willChangeValueForKey:和- didChangeValueForKey:通知觀察者

4、當一個property沒有觀察者時,刪除重寫的方法

5、當沒有observer觀察任何一個property時,刪除動態創建的子類

空說無憑,簡單驗證下。

  1. @interface Sark : NSObject  
  2. @property (nonatomic, copy) NSString *name;  
  3. @end  
  4.   
  5. @implementation Sark  
  6. @end 
  1. Sark *sark = [Sark new];  
  2. // breakpoint 1  
  3. [sark addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];  
  4. // breakpoint 2  
  5. sark.name = @"薩薩薩";  
  6. [sark removeObserver:self forKeyPath:@"name"];  
  7. // breakpoint 3  

斷住后分別使用- class和object_getClass()打出sark對象的Class和真實的Class

  1. // breakpoint 1  
  2. (lldb) po sark.class  
  3. Sark  
  4. (lldb) po object_getClass(sark)  
  5. Sark  
  6.   
  7. // breakpoint 2  
  8. (lldb) po sark.class  
  9. Sark  
  10. (lldb) po object_getClass(sark)  
  11. NSKVONotifying_Sark  
  12.   
  13. // breakpoint 3  
  14. (lldb) po sark.class  
  15. Sark  
  16. (lldb) po object_getClass(sark)  
  17. Sark  

上面的結果說明,在sark對象被觀察時,framework使用runtime動態創建了一個Sark類的子類 NSKVONotifying_Sark,而且為了隱藏這個行為,NSKVONotifying_Sark重寫了- class方法返回之前的類,就好像什么也沒發生過一樣。但是使用object_getClass()時就暴露了,因為這個方法返回的是這個對象的isa 指針,這個指針指向的一定是個這個對象的類對象

然后來偷窺一下這個動態類實現的方法,這里請出一個NSObject的擴展NSObject+DLIntrospection,它封裝了打印一個類的方法、屬性、協議等常用調試方法,一目了然。

  1. @interface NSObject (DLIntrospection)  
  2. + (NSArray *)classes;  
  3. + (NSArray *)properties;  
  4. + (NSArray *)instanceVariables;  
  5. + (NSArray *)classMethods;  
  6. + (NSArray *)instanceMethods;  
  7.   
  8. + (NSArray *)protocols;  
  9. + (NSDictionary *)descriptionForProtocol:(Protocol *)proto;  
  10.   
  11. + (NSString *)parentClassHierarchy;  
  12. @end  

然后繼續在剛才的斷點處調試:

  1. // breakpoint 1  
  2. (lldb) po [object_getClass(sark) instanceMethods]  
  3. <__NSArrayI 0x8e9aa00>(  
  4. - (void)setName:(id)arg0 ,  
  5. - (void).cxx_destruct,  
  6. - (id)name  
  7. )  
  8. // breakpoint 2  
  9. (lldb) po [object_getClass(sark) instanceMethods]  
  10. <__NSArrayI 0x8d55870>(  
  11. - (void)setName:(id)arg0 ,  
  12. - (class)class,  
  13. - (void)dealloc,  
  14. - (BOOL)_isKVOA  
  15. )  
  16. // breakpoint 3  
  17. (lldb) po [object_getClass(sark) instanceMethods]  
  18. <__NSArrayI 0x8e9cff0>(  
  19. - (void)setName:(id)arg0 ,  
  20. - (void).cxx_destruct,  
  21. - (id)name  
  22. )  

首先就有個扎眼的- .cxx_destruct冒出來,這貨是個啥?詳細的探究請參考我的另一篇文章

大概就是說arc下這個方法在所有dealloc調用完成后負責釋放所有的變量,當然這個和KVO沒啥關系了,回到正題。

從上面breakpoint2的打印可以看出,動態類重寫了4個方法:

1、- setName:最主要的重寫方法,set值時調用通知函數

2、- class隱藏自己必備啊,返回原來類的class

3、- dealloc做清理犯罪現場工作

4、- _isKVOA這就是內部使用的標示了,判斷這個類有沒被KVO動態生成子類

接下來驗證一下KVO重寫set方法后是否調用了- willChangeValueForKey:和- didChangeValueForKey:

最直接的驗證方法就是在Sark類中重寫這兩個方法:

  1. @implementation Sark  
  2.   
  3. - (void)willChangeValueForKey:(NSString *)key  
  4. {  
  5.     NSLog(@"%@", NSStringFromSelector(_cmd));  
  6.     [super willChangeValueForKey:key];  
  7. }  
  8.   
  9. - (void)didChangeValueForKey:(NSString *)key  
  10. {  
  11.     NSLog(@"%@", NSStringFromSelector(_cmd));  
  12.     [super didChangeValueForKey:key];  
  13. }  
  14.   
  15. @end  

 

責任編輯:閆佳明 來源: blog.sunnyxx
相關推薦

2011-07-19 17:24:31

Objective-C 對象

2011-07-27 16:55:12

Objective-c 閉包

2011-08-10 18:07:29

Objective-C反射

2013-06-20 10:40:32

Objective-C實現截圖

2013-03-27 12:54:00

iOS開發Objective-C

2011-05-11 15:58:34

Objective-C

2011-05-11 11:20:26

Objective-C

2013-08-21 13:26:43

Objective-CNSDate說明

2011-05-11 13:54:08

Objective-C

2011-05-11 15:45:50

內存管理Objective-C

2011-08-02 13:16:36

Objective-C 語法 函數

2011-08-04 11:15:46

Objective-C 構造函數 構造方法

2011-05-11 14:06:49

Objective-C

2011-08-04 14:58:37

Objective-C Cocoa NSString

2013-08-21 14:57:42

objective-c問題

2011-08-03 16:55:05

Objective-C 代理

2011-08-04 09:35:09

Objective-C 編碼規范

2014-04-30 10:16:04

Objective-CiOS語法

2012-03-07 13:43:59

Objective-C

2011-07-08 13:49:46

Objective-C UUID
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 岛国av免费在线观看 | 久久久成人免费视频 | 欧美视频精品 | 一区二区在线 | 日韩精品在线观看网站 | 久久久久99 | 日本久草视频 | 久久精彩视频 | 一区二区在线不卡 | 免费看91| 中文字幕视频在线免费 | 久久精品16 | 亚洲国产一 | 人人玩人人添人人澡欧美 | 亚洲成网| 91在线视频网址 | 亚洲精品视频免费观看 | 国产一区二区免费在线 | 精品久久一区 | 国产黄色av网站 | 在线激情视频 | 天天射影院| 人人看人人搞 | 国产一区在线免费观看 | av在线亚洲天堂 | 一区二区三区亚洲 | 精品在线一区二区三区 | 成人性视频在线 | 天天插天天搞 | 欧美精品网站 | 天天爽网站 | 国产欧美在线一区 | 91观看 | 久久久久成人精品免费播放动漫 | 欧美日韩专区 | 狠狠操操| 国内精品久久久久久久影视简单 | 99精品久久久 | 午夜免费视频 | 日韩精品免费在线观看 | 欧美a级成人淫片免费看 |