//kvo用法
-(void)testKVO
{
//什么是kvo
//key value observing 键值监听
//实例: 汽车显示频显示当前车的速度
newCar = [[Car alloc] init];
//实时监控, 车速一旦变化, 立马显示
//作用: 当newCar中speed属性变化的时候, 执行self中指定方法
[newCar addObserver:self forKeyPath:@"speed" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
newCar.speed = 0;
newCar.speed = 10;
newCar.speed = 60;
newCar.speed = 120;
newCar.speed = 120;
}
//这个方法是每个对象都有的方法
//参数1: 表示那个属性改变了
//参数2: 那个对象的属性改变了
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
double speed = [[object valueForKeyPath:keyPath] doubleValue];
NSLog(@"speed = %f",speed);
}
//需要在最后移除这个监听
-(void)dealloc
{
[newCar removeObserver:self forKeyPath:@"speed"];
}
//kvc用法
-(void)testKVC
{
//1. KVC
// 是啥: Key Value Coding 键值编码
// 干嘛: 以字符串作为key, 访问对象属性的一种方式
Car *car = [[Car alloc] init];
car.type = @"BMW";
car.speed = 200;
[car setValue:@"奇瑞QQ" forKey:@"type"];
[car setValue:@(120) forKey:@"speed"];
NSLog(@"t = %@,s = %f",[car valueForKey:@"type"],
[[car valueForKey:@"speed"] doubleValue]);
//解析中可能出现的问题
[car setValue:@"奇瑞QQ" forKey:@"unknown"];
// keyPath的使用 - 处理多层嵌套的属性
Engine *e = [[Engine alloc] init];
e.power = 1000000;
car.engine = e;
//修改power,这个是Car属性里面一个对象的属性,这时候要用forKeyPath
[car setValue:@(2000000) forKeyPath:@"engine.power"];
NSLog(@"p = %f",[[car valueForKeyPath:@"engine.power"] doubleValue]);
// 字典转化为对象
NSDictionary *dict = @{@"type":@"dongfeng",@"speed":@(20000)};
Car *newCar = [[Car alloc] init];
[newCar setValuesForKeysWithDictionary:dict];
NSLog(@"%@ %f",newCar.type,newCar.speed);
}
//消除找不到到字符串对应的属性警告,这个要写在赋值对象中,比如上面的Car中
-(void)setValue:(id)value forUndefinedKey:(NSString *)key
{
NSLog(@"key = %@",key);
}
//有时候属性是结构体,而必须要传值是对象类型,可以使用下列方法
NSValue *v=[NSValue valueWithCGRect:CGRectMake(290, 0, 30, 44)];