iOS KVO 观察者模式实现方式

原文:http://gaoyong.diandian.com/post/2012-08-08/40031793795 

KVO (Key Value Observing)是ios里面一种特别方便的机制用于“捕捉”对象属性的变化。在概念理解上,是设计模式里面观察者模式的一种实践。 

拿一个具体的例子来讲: 

有一个数据对象EmployeeData,该对象有一个属性salary 

有一个ViewController 用于显示对象EmployeeData的属性salary的值 

当salary的值发生变化的时候,ViewController如何显示变化后的新值。 

方案一: 

    “可以在EmployeeData类弱引用ViewController类,然后在EmployeeData数据发生变化时,调 

    用ViewController类的回调函数。这个方法虽然能达到目的,但是会破坏EmployeeData的完整 

    性,一个负责数据管理的类,不应当依赖另一个负责视图控制的类;换句话说,EmployeeData 

    类不应该知道关于ViewController类的任何事情,甚至不需要知道其从在” 

方案二: 

使用ios提供的消息中心(NSNotificationCenter)。在此EmployeeData为消息生产者,ViewController为消息消费者。当salary数据发生变化时发送一个消息既可。 

ViewController接收到salary数据变化的通知做相对应的业务处理。不足之处如同方案一,EmployeeData对象的salary每次变动都需要发送“通知”。这项工作对EmployeeData自身来讲毫无意义。 

方案三: 

在ViewController中将自身(self)设置为EmployeeData salary属性值变化的观察者。当salary值发生变化时,执行一个回调方法。这样对“EmployeeData”来讲不用关心除自身业务以 

外的事情。避免了方案一和方案二的瑕疵。对ViewController来讲关注谁的变化,注册自己为其的观察者既可。间接轻便。 



下面是一些核心的代码。 



  1. //  
  2. //  EmployeeData.h  
  3. //  KVOExample  
  4. //  
  5. //  Created by gaoyong on 12-8-8.  
  6. //  Copyright (c) 2012年 gaoyong. All rights reserved.  
  7. //  
  8.                    
  9. #import <Foundation/Foundation.h>  
  10.                    
  11. @interface EmployeeData : NSObject {  
  12.                        
  13.     NSString *salary;  
  14. }  
  15.                    
  16. @property(nonatomic,retain) NSString *salary;  
  17.                    
  18. @end  
  19.   
  20.    
  21.   
  22. //  
  23. //  EmployeeData.m  
  24. //  KVOExample  
  25. //  
  26. //  Created by gaoyong on 12-8-8.  
  27. //  Copyright (c) 2012年 gaoyong. All rights reserved.  
  28. //  
  29.                   
  30. #import "EmployeeData.h"  
  31.                   
  32. @implementation EmployeeData  
  33. @synthesize salary;  
  34.                   
  35. @end  
  36.   
  37.    
  38.   
  39. //  
  40. //  ViewController.h  
  41. //  KVOExample  
  42. //  
  43. //  Created by gaoyong on 12-8-8.  
  44. //  Copyright (c) 2012年 gaoyong. All rights reserved.  
  45. //  
  46.                 
  47. #import <UIKit/UIKit.h>  
  48.                 
  49. @interface ViewController : UIViewController {  
  50.                     
  51.     UILabel *salary;  
  52. }  
  53.                 
  54. @property(nonatomic,retain) IBOutlet UILabel *salary;  
  55.                 
  56. @end  
  57.   
  58.    
  59.   
  60.    
  61.   
  62. //  
  63. //  ViewController.m  
  64. //  KVOExample  
  65. //  
  66. //  Created by gaoyong on 12-8-8.  
  67. //  Copyright (c) 2012年 gaoyong. All rights reserved.  
  68. //  
  69.         
  70. #import "ViewController.h"  
  71. #import "EmployeeData.h"  
  72.         
  73.         
  74. @interface ViewController () {  
  75.         
  76.     EmployeeData *employeeData;  
  77. }  
  78.         
  79. @end  
  80.         
  81. @implementation ViewController  
  82. @synthesize salary;  
  83.         
  84. - (void)viewDidLoad  
  85. {  
  86.     [super viewDidLoad];  
  87.     // Do any additional setup after loading the view, typically from a nib.  
  88.             
  89.     employeeData = [[EmployeeData alloc] init];  
  90.     [employeeData addObserver:self forKeyPath:@"salary" options:NSKeyValueObservingOptionNew context:nil];  
  91. }  
  92.         
  93. -(void)viewDidAppear:(BOOL)animated {  
  94.             
  95.     //employeeData.salary = @"20";  
  96.     //salary.text = employeeData.salary;  
  97.     employeeData.salary = @"20";  
  98.     employeeData.salary = @"200";  
  99.     employeeData.salary = @"2000";  
  100.     employeeData.salary = @"20000";  
  101.     employeeData.salary = @"200000";  
  102. }  
  103.         
  104. - (void)viewDidUnload  
  105. {  
  106.     [super viewDidUnload];  
  107.     // Release any retained subviews of the main view.  
  108. }  
  109.         
  110. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  111. {  
  112.     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);  
  113. }  
  114.         
  115. -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {  
  116.             
  117.     NSLog(@"observeValueForKeyPath is run"); // 美妙在这里:这一行会打印5次。  
  118.             
  119.     if (object == employeeData && [keyPath isEqualToString:@"salary"]) {  
  120.                 
  121.         self.salary.text = employeeData.salary;  
  122.     }  
  123. }  
  124.         
  125. -(void) dealloc {  
  126.         
  127.     [employeeData removeObserver:self forKeyPath:@"salary"];  
  128. }  
  129.         
  130. @end  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值