【iOS】KVC 与 KVO

时间:2025-01-29 09:39:37
*KVO”:key value Observer(键值观察),观察者模式.(检测模型变化用的多)
*目的:通常用于观察某个对象的某个属性发生变化,及时做出相应.

二、KVC的使用方式

KVC被称为iOS开发平台的大招!!! 能快速修改对象属性。

*[p1setValue:@“xxxx”forKeyPath:@“name”];修改指定对象属性.
*[arrvalueForKeyPath:@“”];  获取对象属性.
*KVC通过键能直接取得数组.
*在使用KVC, 一定要保证键值是存在.
*原理KVC取值时, 如果发现取值的对象不包含指定的键值,会自动进入对象内部成员进行查找.

三、KVO的使用方式

*KVO通常用于观察对象某个属性发生变化时,做出相应的反应.(多用于观察模型数据)
*KVO和通知中心的一个区别 : KVO只能盯着某个对象(在当前区域内部工作),通知中心可以穿越很多层(如viewController).
*KVO使用步骤:
*1.[stuaddObserver:selfforKeyPath:@"name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"myObserver"];
*2.observeValueForKeyPath.  当指定键值发生改变时, 会自动调用这个方法
*3.removeObserver. 所有观察者模式的性能都不好,需要及时移除。

直接上代码:
//
//  
//  KVC----KVO
//
//  Created by neng on 14-6-21.
//  Copyright (c) 2014年 neng. All rights reserved.
//

#import ""
#import ""
#import ""
#import ""

@interface XNViewController ()

@end
/**
 *  KVC: Key Value Coding(键值编码)
 *  间接修改/获取对象的属性, 降低类与类之间的耦合度.
 *  KVO: Key Value Observer(键值观察)
   KVO通常用于观察”对象的某个属性“发生变化时,及时做出响应!
   而NSNotificationCenter是需要POST"通知字符串"(表示监听的事件类型)的对象存在,通知中心才能够工作!
 */

@implementation XNViewController

- (void)viewDidLoad {
	[super viewDidLoad];
	//1.简单的修改对象属性
	[self kvcDemo1];
	//2.对于子类, 也能直接修改
	[self kvcDemo2];
	//3.修改对象的book属性. (相当麻烦, 好要创建book对象).KVC一句话
	[self kvcDemo3];
	//4.获取对象的属性值. 可批量获取(如果是数组的话).
	[self kvcDemo4];

	//KVO 演示
	[self kvoDemo];
}

- (void)kvoDemo {
	XNStudent *stu = [[XNStudent alloc] init];
	 = @"xuneng";
	//设置监听对象
	//1》 负责观察的对象 self
	//2》 观察的键值路径
	//3》 观察的选项
	//4》 上下文:通常用于区分不同的观察事件
	[stu addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"myObserver"];

	 = @"neng"; //修改

	//所有观察者模式的性能都不好, 需要及时移除
	[stu removeObserver:self forKeyPath:@"name"];

	 = @"xu";  //移除后再次修改
}

/**
   当KVO指定的对象键值发生改变时, 会自动调用该方法
   name:      观察的键值
   object:    观察的对象
   change:    修改的字典(新旧数值)
   context:   指定观察者时传入的上下文
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
	NSLog(@"|-- %@ --|-- %@ --|-- %@ --|-- %@--|", keyPath, object, change, context);
}

/**
 *简单的修改对象属性
 */
- (void)kvcDemo1 {
	//1.原始的方式. 点语法修改对象属性的值
	XNPerson *p1 = [[XNPerson alloc] init];
	 = @"xuneng";
	 = 24;
	//    NSLog(@"%@ , %d",,);
	NSLog(@"KVC1 demo1--> %@", p1); //这样直接调用description方法.

	//来修改
	[p1 setValue:@"xxxx" forKeyPath:@"name"];
	[p1 setValue:@"10" forKeyPath:@"age"];
	NSLog(@"KVC2 demo1--> %@ , %d", , );
}

/**
 *对于子类, 也能直接改
 */
- (void)kvcDemo2 {
	//1.传统方法
	XNStudent *p1 = [[XNStudent alloc] init]; //学生
	 = @"student xuneng";
	 = 22;
	//    NSLog(@"%@ , %d",,);
	NSLog(@"KVC1 demo2--> %@", p1); //这样直接调用description方法.

	//来修改子类
	[p1 setValue:@"xxxx" forKeyPath:@"name"];
	[p1 setValue:@"10" forKeyPath:@"age"];
	NSLog(@"KVC2 demo2--> %@ , %d", , );
}

/**
 *修改对象的book属性. (相当麻烦, 好要创建book对象).KVC一句话
 */
- (void)kvcDemo3 {
	//1.传统方法
	XNStudent *p1 = [[XNStudent alloc] init]; //学生
	 = @"student xuneng";
	 = 22;
	XNBook *myBook = [[XNBook alloc] init];
	 = @"iOS";
	 = myBook;
	NSLog(@"KVC1 demo3--> %@", p1);

	//的方法
	[p1 setValue:@"iPhone" forKeyPath:@""]; //学生里的book,book里的bookName
	NSLog(@"KVC2 demo3--> %@", p1);
}

/**
 *获取对象的属性值. 可批量获取(如果是数组的话).
 */
- (void)kvcDemo4 {
	XNStudent *p1 = [[XNStudent alloc] init]; //学生1
	 = @"student1 xuneng";
	 = 24;
	XNBook *myBook1 = [[XNBook alloc] init];
	 = @"iOS";
	 = myBook1;

	XNStudent *p2 = [[XNStudent alloc] init]; //学生2
	 = @"student2 xuneng";
	 = 23;
	XNBook *myBook2 = [[XNBook alloc] init];
	 = @"iPhone";
	 = myBook2;

	NSArray *arr = @[p1, p2];

	//1.普通方法获取数组中对象的属性
	NSMutableArray *arrBook = [[NSMutableArray alloc] init];
	for (XNStudent *stu in arr) {
		[arrBook addObject:];
	}
	NSLog(@"KVC1 demo4--> %@", arrBook);

	//方法来获取数组中对象
	NSLog(@"KVC2 demo4--> %@", [arr valueForKeyPath:@""]);
}

@end


例子源码下载/detail/xn4545945/7571719

转载请注明出处:/xn4545945