Objective-C语法之KVO的使用

简介:

上篇我们讲到了KVC,这篇我们学习KVO,全名为:Key Value Observing,直译为:基于键值的观察者。

那它有什么用呢?KVO主要用于视图交互方面,比如界面的某些数据变化了,界面的显示也跟着需要变化,那就要建立数据和界面的关联。

ObjC中提供的KVO就是解决这种问题的。以下用显示页面观察学生的课程名称变化的例子来说明KVO的使用。

学生类命名为:Student,页面类是:PageView.

上图来自苹果官网:图中的BankObject好比PageView,PersonObject好比Student,

PageView观察Student的变化。

1、添加Student学生类。

.h

#import <Foundation/Foundation.h>
@interface Student : NSObject
{
    NSString *name;
    NSString *courseName;
}
-(void)changeCourseName:(NSString*) newCourseName;
@end

类中有name,和课程名称courseName,添加一个可以改变课程名称的方法changeCourseName。一会用来做对比,看直接改变课程名称时会不会有回调。

实现文件.m

#import "Student.h"

@implementation Student
-(void)changeCourseName:(NSString*) newCourseName
{
    courseName = newCourseName;
}
@end

实现类把方法实现了。

2、页面类实现

.h文件

#import <Foundation/Foundation.h>
@class Student;
@interface PageView : NSObject
{
    Student *student;
}
-(id)init:(Student*)initStudent;
@end

.m文件

#import "PageView.h"
#import "Student.h"

@implementation PageView
-(id)init:(Student*)initStudent
{
    if (self = [super init]) {
        student = initStudent;
        [student addObserver:self
                  forKeyPath:@"courseName"
                     options:NSKeyValueObservingOptionOld
                            |NSKeyValueObservingOptionNew context:nil];
    }
    return self;
}

- (void) dealloc{
    [student removeObserver:self forKeyPath:@"courseName" context:nil];
    [super dealloc];
}

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context
{
    if ([keyPath isEqual:@"courseName"]) {
        NSLog(@"PageView课程被改变了");
        NSLog(@"PageView新课程是:%@ 老课程是:%@", [change objectForKey:@"new"],[change objectForKey:@"old"]);
    }
}
@end

init初始化时,向student实例添加观察者,在释放的时候移除观察者。

3、实现观察

在main函数中

#import "Student.h"
#import "Course.h"
#import "PageView.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *student = [[[Student alloc]init]autorelease];
        [student changeCourseName:@"数学课"];
        NSLog(@"初始值:%@", [student valueForKey:@"courseName"]);

        //创建页面实例
        PageView *pageview = [[[PageView alloc]init:student]autorelease];

        [student setValue:@"化学课" forKey:@"courseName"];

    }
    return 0;
}

新建一个student的实例,设置他的课程是数学课,然后创建页面类的时候,用student初始化。这是页面类已经观察着学生的课程了。

再给课程设置新的值为化学课。这时候运行打印结果:

2012-07-24 16:29:21.561 objectiveC[2192:403] 初始值:数学课

2012-07-24 16:29:21.565 objectiveC[2192:403] PageView课程被改变了

2012-07-24 16:29:21.566 objectiveC[2192:403] PageView新课程是:化学课 老课程是:数学课

可以看到Pageview类中的回调被调用,Pageview接收到学生课程数据更新的信息。

4、直接改变课程信息对比

#import "Student.h"
#import "Course.h"
#import "PageView.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *student = [[[Student alloc]init]autorelease];
        [student changeCourseName:@"数学课"];
        NSLog(@"初始值:%@", [student valueForKey:@"courseName"]);

        //创建页面实例
        PageView *pageview = [[[PageView alloc]init:student]autorelease];

        [student setValue:@"化学课" forKey:@"courseName"];
        [student changeCourseName:@"英语课"];
        NSLog(@"直接改变的课程为:%@", [student valueForKey:@"courseName"]);

    }
    return 0;
}

直接调用changeCourseName方法改变课程,打印结果:

2012-07-24 16:32:06.230 objectiveC[2240:403] 初始值:数学课

2012-07-24 16:32:06.237 objectiveC[2240:403] PageView课程被改变了

2012-07-24 16:32:06.238 objectiveC[2240:403] PageView新课程是:化学课 老课程是:数学课

2012-07-24 16:32:06.239 objectiveC[2240:403] 直接改变的课程为:英语课

可以看到,这时Pageview的回调没被调用到。说明只有通过键值编码(KVC)改变的值,才会回调观察者注册的方法。

这里是苹果官网的关于KVO的文档,英文好的朋友可以看看:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA

时间: 2024-11-03 21:12:42

Objective-C语法之KVO的使用的相关文章

初学Objective - C语法之代码块(block)

一.block声明 1.无参数,无返回值: void (^sayHi)(); 2.有参数,有返回值: NSInteger (^operateOfValue)(NSInteger num); block的声明:返回值类型(^block变量名)(参数列表) 脱字符(^)是块的语法标记 二.block实现 block变量名 = ^返回值类型(参数列表) 1.  sayHi = ^{ NSLog(@"你好"); }; 2. operateOfValue = ^ NSInteger (NSInt

Objective-C语法之KVO使用

本文转自:http://blog.csdn.net/yuquan0821/article/details/6646400/ 一,概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了. 二,使用方法 系统框架已经支持KVO,所以程序员在使用的时候非常简单. 1. 注册,指定被观察者的属性, 2. 实现回调方法 3. 移除观察 三,实例: 假设一个

《黑马程序员》 NSArray和NSMutableArray的使用(Objective - c语法)

------- <a href="http://www.itheima.com" target="blank">Windows Phone 7手机开发</a>.<a href="http://www.itheima.com" target="blank">.Net培训</a>.期待与您交流! ------- 1 NSArray 的使用方法 • Foundation中数组(NSAr

iOS开发——语法篇OC篇&amp;高级语法精讲二

Objective高级语法精讲二 Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和转发.下面通过分析Apple开源的Runtime代码(我使用的版本是objc4-646.tar)来深入理解Objective-C的Runtime机制. Runtime数据结构 在Objective-C中,使用[receiver message]语法并不会马上执行receiver对象的message方

iOS 版本更新摘要(三)iOS 8.x

[What's New in iOS 8.x](https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html#//apple_ref/doc/uid/TP40014205-SW1 "What's New in iOS 8.x") ####iOS 8.0 #App Extensions iOS 8.0 提供了 app 扩展点,让你可以在系统的选择区域扩展选择区域.

Pentaho BI server 中 CCC table Component 的使用小技巧

我使用的版本 Pentaho BI Server 5.3.0.0.213 CDE/CDF/CDA/CCC 15.04.16 stable Q: 如何设置表格中各种提示文字的语言(默认为英语)? CDE -> table Component -> Advanced Properties -> oLanguage,编辑该属性,语法需满足 JavaScript Objective 的语法,可以设置的参数如下: { "sProcessing": "Processin

iOS开发核心语言Objective C —— 面向对象思维、setter和getter方法及点语法

本分享是面向有意向从事iOS开发的伙伴们.或者已经从事了iOS的开发人员.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基础,建议您先翻阅我之前分享的iOS开发分分钟搞定C语言系列.然后在開始Objective C语言的学习,假设您遇到问题也能够与我探讨,另外将无偿分享自己整理的大概400G iOS学习视频及学习资料.都是干货哦.能够新浪微博私信?关注极客James.期待与您的共同学习和探讨.! 由于时间有限,每天在工作之余整理的学习分享.难免有不足之

oc 语法 kvo

点名主题 : kvo就是一个类来监听另外一个类的变量,当变量发生改变的时候来通知这个类. 举个例子: 创建一个人的类,人的类中有一个银行卡:创建一个银行卡的类,银行卡的类中有一个钱的变量: 我们来用人的类来监听银行卡中的钱数,当银行卡中的钱数发生改变的时候来通知人: 下面我们来实现这个例子: 新建一个 创建一个person类 person.h #import <Foundation/Foundation.h> @class BankCard; @interface Person : NSObj

Objective - C中属性和点语法的使用

一.属性 属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性 OC中的属性机制提供了便捷的设置和获取实例变量的方式,或者说属性提供了一个默认的设置器和访问器的实现:属性提供的方法是现实可配置的,属性的好处:相当于自己编写这一对方法,属性提供了一系列清晰分明的说明参数来定义设置器和访问器的行为,编译器可以根据你设置的说明参数为你生成相应的方法,减少你的代码量和维护工作量 设置器(sette