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

------<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>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值