初识Objecive-C 之 键值观察(KVO)

来源:互联网 发布:知乎个性域名是什么 编辑:程序博客网 时间:2024/05/18 09:10

键值观察(KVO):Key-Value-Observing它基于键值编码的一种技术。利用键值观察可以注册成为一个对象的观察者,在该对象的某一个变化时收到通知。

编写键值观察三部曲:

  1. 注册成为观察者
  2. 观察者定义KVO的回调
  3. 移除观察者
下面以保姆观察小孩的happVal值为例:

#import<Foundation/Foundation.h>


@interface Child :NSObject


@property (assign)int happyVal;


@end


#import<Foundation/Foundation.h>

@classChild;

@interface Nurse :NSObject


@property (retain)Child *child;


- (id) initWithChild: (Child *)child;//被观察者


@end

-------------------------------------------------------------------

#import<Foundation/Foundation.h>

@classChild;

@interface Nurse :NSObject


@property (retain)Child *child;


- (id) initWithChild: (Child *)child;//被观察者


@end


#import"Nurse.h"

#import"Child.h"

@implementation Nurse


//便利构造函数

-(id)initWithChild:(Child *)child{

   if (self=[superinit]) {

       self.child=child;

       ////注册观察者  对象是小孩  值的改变调用回调方法

        [childaddObserver:self

               forKeyPath:@"happyVal"//观察的属性happyVal

                  options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld//观察新值和旧值的变化

                  context:nil];

    }

   return self;

}

//观察者的回调方法

- (void)observeValueForKeyPath:(NSString *)keyPath

                      ofObject:(id)object

                        change:(NSDictionary *)change

                       context:(void *)context

{

   //输出change的值

   NSLog(@"%@",change);

}


- (void)dealloc

{

   //移除观察者观察的属性

    [self.childremoveObserver:selfforKeyPath:@"happyVal"];

   //释放观察者对象

    [self.childrelease];

    [superdealloc];

}


@end


-----------------------------------------------------------------------------------



#import<Foundation/Foundation.h>

#import"Nurse.h"

#import"Child.h"

int main(int argc,constchar * argv[])

{


   @autoreleasepool {        

       Child *child = [[Childalloc]init];

       Nurse *nurse = [[Nursealloc]initWithChild:child];

       BOOL isTrue = YES;

       while (isTrue) {

           NSDate *dt = [NSDatedate];

            [[NSRunLoopcurrentRunLoop]runUntilDate:[dtdateByAddingTimeInterval:20]];

            isTrue=NO;

           NSLog(@"监听结束");

        }


    }

   return 0;

}