您的位置:首页 > 职场人生

黑马程序员—OC基础--初探 “KVO”

2015-05-26 14:57 106 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ———

/*****************************************

 *      今天对 “KVO(键值监听)”进行学习.收获如下:

 *

 *    KVO的用处⭐️:例如,如果程序的需求是:在数据模型组件的状态数据发生改变时,视图组件能动态地更新自己。

 *  方案1⃣️:让数据模型组件持有一个视图组件的引用,当数据发生改变时,数据模型组件回调视图组件的方法使其得到更新。

 *  不足:很显然,视图组件应该依赖于数据组件。如果用这种方法,就会形成一种双向依赖,这是很糟糕的设计。

 *  

 *  方案2⃣️:利用ios提供的消息中心(NSNotificationCenter)来解决,让数据组件作消息生产者,视图组建作消息消费者。

 *          每当数据组件的状态数据发生改变时,数据组件向消息中心发送消息,该消息会激发视图组件来消费该消息。

 *  不足:虽然避免了双向依赖,但数据组件和视图组件都要与ios的消息中心耦合,每次更新都需要向ios消息中心发送消息

 *

 *****************************************

 *  

 *    KVO⭐️: KVO机制由NSKeyValueObserving协议提供支持,而NSObject遵守了该协议(即所有类都遵守了该协议)。

 *

 *  1.常用方法如下:

 *      __

 *     |   
1⃣️ addObserver: forKeyPath: options: context:
注册一个监听器用于监听指定的key路径

 *     |   
2⃣️ removeObserver: forKeyPath:
为key路径删除制定的监视器

 *    <    
3⃣️ removeObserver: forKeyPath: context:
为key路径删除指定的监视器,指示多了一个context参数

 *     |   
4⃣️ observeValueForKeyPath: ofObject: change: context:

 *     |__     
监听器对象需重写该方法,来触发监听器。

 *

 *  2.KVO整体来说步骤非常简单:1⃣️为被监听的对象注册监听器(通常是数据模型组件)。
2⃣️重写监听器触发方法(上述第4条)。

 *

 *

 *******************************************/

代码实现:

#import <Foundation/Foundation.h>
/**************************************************************************************/        // LBXYItem类
@interface LBXYItem : NSObject              //声明LBXYItem类

@property(nonatomic, copy) NSString* name;
@property(nonatomic, assign) int price;

@end
/********/
@implementation LBXYItem                    //实现LBXYItem类

@synthesize name;
@synthesize price;

@end
/**************************************************************************************/

/**************************************************************************************/        // LBXYItemView类
@interface LBXYItemView : NSObject          //声明LBXYItemView类

@property(nonatomic, weak) LBXYItem* item;
- (void) showItemInfo;

@end
/*******/
@implementation LBXYItemView                //实现LBXYItemView类

@synthesize item = _item;

- (void) showItemInfo
{
NSLog(@"item物品为:%@,物品价格为:%d\n\n", self.item.name, self.item.price);
//NSLog(@"\n");
}

//覆写setItem:方法
- (void) setItem : (LBXYItem *) item
{
_item = item;
//为item添加监听器,监听对象为自身,监听自身的name属性改变
[self.item addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
//为item添加监听器,监听item的price属性
[self.item addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew context:nil];
}

//覆写监听器触发方法
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"-------observeValueForKeyPath方法被调用---------------");

NSLog(@"被修改的keyPath为:%@",keyPath);
NSLog(@"被修改的对象为:%@",object);
NSLog(@"新修改的属性值为:%@",[change objectForKey:@"new"]);
NSLog(@"被修改的上下文为:%@\n\n",context);
}

-(void) dealloc
{
//删除监听器
[self.item removeObserver:self forKeyPath:@"name"];
[self.item removeObserver:self forKeyPath:@"price"];
}

@end
/**************************************************************************************/

int main(int argc, const char * argv[])
{
@autoreleasepool
{
LBXYItem* item = [[LBXYItem alloc] init];
item.name = @"初设name";
item.price = 1;
LBXYItemView* itemView = [[LBXYItemView alloc] init];
itemView.item = item;
[itemView showItemInfo];
//再次更改item对象的属性,将会激发监听器方法
item.name = @"更改name";
item.price = 2;
itemView.item.name = @"再次更改name";
itemView.item.price = 3;

}
return 0;
}<span style="color:#4bd157;">
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: