cocoa 自动键值观察(KVO)--笔录

要实现自动的键值观察,可以很简单的几行代码就能实现该功能:

程序功能描述:

建立一个Observer(观察者)类以及一个Target(被观察者)类,通过Observer类实例对象观察Target实例对象的Age属性!也就是说,

当age的值发生变化时,Observer实例对象应该能收到通知。

代码:

1.Target.h 和Target.m文件

//
//  Target.h
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Target : NSObject
@property   int age;  // for auto KVO 

@end


//
//  Target.m
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import "Target.h"

@implementation Target
@synthesize age;    // for auto KVO


@end
Target类,就这么简单的定义,可以看出来,它只声明了和定义一个age变量!注意,它是用@property 和@systhesize 两个关键字来声明和定义的!!


2.Observer.h 和 Observer.m文件

//
//  Observer.h
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Observer : NSObject

@end

//
//  Observer.m
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import "Observer.h"

@implementation Observer
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"age"]) {
        Class classInfo = context;
        NSString *className = [classInfo class];
        NSLog(@" >> class : [%@] , Age changed", className);
        NSLog(@" >> old age is %@", [change objectForKey:@"old"]);
        NSLog(@" >> old age is %@", [change objectForKey:@"new"]);
        
    }
    else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}
@end

可以看得出来,Observer类基本上什么都没有做,它就实现了一个类对象的实例方法:observerValueForKeyPath。


3. main.m 文件

//
//  main.m
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Observer.h"
#import "Target.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Observer *observer = [[[Observer alloc] init] autorelease];
        Target * target = [[[Target alloc] init] autorelease];
        
        [target addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:[Target class]]; 
        
        [target setAge:500];
        [target removeObserver:observer forKeyPath:@"age"];
        
        
    }
    return 0;
}

main文件中,要点有三个:

1)将观察者和被观察者注册,即addObserver函数,为消息接收者添加观察者。

2)使用setAge这种默认访问方法来改变写值。

3)解除注册removeObserver (不调用该方法,编译器会打印出一堆信息说,你的KVO还在注册)



4.小结:

实现自动的键值观察(KVO)的要素:

1) age的声明和定义必须要用@property和@synthesize; //

2)观察者类要实现observeValueForKeyPath 方法来接受处理变更的通知

3)将观察者和被观察者注册,如[target addObserver:...] ,

4)使用默认的属性访问方法来改写属性的值,如[target setAge:500];

5)解除注册。


6. 其他

想了解手动的KVO以及为什么自动的KVO要这样实现,可以看下面的参考文章。


参考文章:

[深入浅出Cocoa]详解键值观察(KVO)及其实现机理     (讲得很详细)

KVO键-值观察编程指南




注:本文章大部分都是参考网络其他的文章,不足之处请多多指教。此处只为了作笔记之。2014-07-30  凌晨






你可能感兴趣的:(cocoa,KVO,键值观察)