zoukankan      html  css  js  c++  java
  • Objective-C:KVO机制

    KVO:key value observer 键值对的观察者
     
    功能:给对象属性添加观察者,用来时时监测对象属性值的改变,一旦属性值发生了改变,观察者就做出相应的反应,提醒用户。在应用中,针对MVC模式,数据库中的数据模型发生变化时,引起视图界面的改变,此时使用KVO进行数据的监测是一个不错的机制。
     
     
    步骤:
    1.添加观察者
    2.接收变动通知
    3.删除观察者
     
    详细介绍:
     
    键值通知枚举

    typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {

        NSKeyValueObservingOptionNew = 0x01,

        NSKeyValueObservingOptionOld = 0x02,

        NSKeyValueObservingOptionInitial = 0x04,

        NSKeyValueObservingOptionPrior= 0x08

     };

     

    内置的通知键

    FOUNDATION_EXPORT NSString *const NSKeyValueChangeKindKey;

    FOUNDATION_EXPORT NSString *const NSKeyValueChangeNewKey;

    FOUNDATION_EXPORT NSString *const NSKeyValueChangeOldKey;

    FOUNDATION_EXPORT NSString *const NSKeyValueChangeIndexesKey;

    FOUNDATION_EXPORT NSString *const NSKeyValueChangeNotificationIsPriorKey ;

    @interface NSObject(NSKeyValueObserving)

    //接受被观察者发出变动后的通知

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

    @end

    @interface NSObject(NSKeyValueObserverRegistration)

    //通过键给对应的属性添加观察者

    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

    //删除观察者

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context;

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

    @end

     

    @interface NSArray(NSKeyValueObserverRegistration)————— 数组的KVO机制

    NSIndexSet 是个无符号整数集合。集合中的元素不可变的、不可重复。常被用来当作索引使用

    //通过键给对应的数组中指定索引的属性添加观察者

    - (void)addObserver:(NSObject *)observer toObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

    //删除观察者

    - (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath context:(void *)context;

    - (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath;

     

    //通过键给对应的数组添加观察者

    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

    //删除观察者

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context;

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

    @end

     

     

    @interface NSSet(NSKeyValueObserverRegistration)—————集合的KVO机制

    //通过键给对应的set集合添加观察者

    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

    //删除观察者

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context;

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

    @end

     

    @interface NSObject(NSKeyValueObserverNotification)————观察者通知

    //对于单个对象

    - (void)willChangeValueForKey:(NSString *)key; 

    - (void)didChangeValueForKey:(NSString *)key;

     

    //对于array数组

    - (void)willChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;

    - (void)didChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;

     

    //对于set集合

    - (void)willChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;

    - (void)didChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;

    @end

    具体演示实例如下:

    要求:将人设置为股票的观察者,一旦股票价格发生改变,就立刻发送即时信息。

    准备工作:

    在控制器视图中添加一个按钮控件并关联事件IBAction,用来点击时改变股票的价格,需要的文件相关截图为:

       

    以下就是代码的实现了:

    Person人类:

    Person.h

    //声明属性

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    {
        NSString *_name;
    }
    @end

    Perosn.m

    //接受观察者发来的即时信息

    #import "Person.h"
    
    @implementation Person
    
    //接收被观察者发生变动后的通知
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        NSLog(@"keyPath:%@,object:%@,change:%@",keyPath,object,change);
    }
    @end

    Stock股票类:

    Stock.h

    //声明属性

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface Stock : NSObject
    {
        NSString *_name;
        CGFloat _price;
    }
    @end

    ViewController控制器类

    //声明属性

    #import "ViewController.h"
    #import "Person.h"
    #import "Stock.h"
    
    @interface ViewController ()
    @property (strong,nonatomic)Person *person;
    @property (strong,nonatomic)Stock *stock;
    @end
    
    @implementation ViewController

    //按钮事件,点击时改变股票的价格

    //按钮事件,改变股票价格
    - (IBAction)buttonClicked:(UIButton *)sender
    {
        CGFloat price = [[self.stock valueForKey:@"_price"] floatValue];
        
        [self.stock setValue:@(price+0.1) forKey:@"_price"];
    }

    //创建对象并添加观察者

    - (void)viewDidLoad {
        [super viewDidLoad];
        //创建人和股票对象
        self.person = [[Person alloc]init];
        [self.person setValue:@"Tom" forKey:@"_name"];
        
        self.stock = [[Stock alloc]init];
        [self.stock setValue:@"sh0001" forKey:@"_name"];
        [self.stock setValue:@12.5 forKey:@"_price"];
        
        
        //添加观察者(观察股票的变动)
        [self.stock addObserver:self.person forKeyPath:@"_price" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    }

    //程序结束,删除观察者

    -(void)dealloc
    {
        //删除观察者
        [self.stock removeObserver:self.person forKeyPath:@"_price"];
    }

    演示结果如下:

    点击第一次,输出股票价格更新即时信息

    2015-10-14 22:02:56.298 02-KVO[5612:319932] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
        kind = 1;
        new = "12.6";
        old = "12.5";
    }

    点击第二次,输出股票价格更新即时信息

    2015-10-14 22:02:56.298 02-KVO[5612:319932] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
        kind = 1;
        new = "12.6";
        old = "12.5";
    }
    2015-10-14 22:03:44.913 02-KVO[5612:319932] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
        kind = 1;
        new = "12.70000038146973";
        old = "12.6";
    }

    点击第三次,输出股票价格更新即时信息

    2015-10-14 22:02:56.298 02-KVO[5612:319932] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
        kind = 1;
        new = "12.6";
        old = "12.5";
    }
    2015-10-14 22:03:44.913 02-KVO[5612:319932] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
        kind = 1;
        new = "12.70000038146973";
        old = "12.6";
    }
    2015-10-14 22:04:09.448 02-KVO[5612:319932] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
        kind = 1;
        new = "12.80000076293945";
        old = "12.70000038146973";
    }
  • 相关阅读:
    绑定class -vue
    二叉树按层打印,并且按层换行的方法
    curl相关知识
    python创建简单的http服务器
    有关rides数据库的想法
    java模拟实现有序表操作
    php静态方法
    php关闭浏览器不终止运行
    php读取图片以二进制输出
    借用face++人脸识别,来识别年龄
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4880890.html
Copyright © 2011-2022 走看看