kvc是用来方便的设置实例的属性值的,比如person类的实例p1有一个name的属性,那么我们可以通过kvc去设置p1的name,语法是:
[ 对象 setValue:@"xiaming" forKey:@"name"];其中xiaoming就是p1的name,这个就相当于用点语法给p1设置name:p1.name = @"xiaoming";
以上就是kvc的简单实用。接下来是kvo,kvo是键值观察,如果我想知道某个值,是否变化,变成什么,不可能一直去访问人家然后进行对比看有没有变化。在xcode中有一个方法用来方便的知道我们要观察的值是否变化,并在变化了之后触发响应的事件,具体操作如下:
假如我想知道某个累的name属性和age 属性是否变化,并在变化后触发响应的处理方法,就要先添加观察者:
1 // 设置两个观察者观察name和age的值是否变化 2 [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:@"name"]; 3 [self addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:@"age"];
以上代码添加了两个需要观察的值,分别是name和age,其中后面的context是我们后期使用kvo时用来区别究竟是name改变还是age改变才触发的kvo。添加了观察者之后,我们需要在程序运行的时候name和age 自动变化,那只好设置一个定时器喽:
声明定时器:
1 NSTimer *timenow;
设置定时器的频率和触发的方法:(设置1.5s触发一次,触发haha:方法)
1 timenow = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(haha:) userInfo:nil repeats:YES];
设置完成后我们需要实现定时器中的haha:方法:
1 //定时器方法 2 -(void)haha:(id)sender{ 3 4 NSString *outString = [NSString stringWithFormat:@"current%d",arc4random()%100]; 5 self.name = outString; 6 self.age = outString; 7 }
在这个方法中我们随机给name和age赋值。
接下来就是设置键值观察:也就是当检测到我们观察的两个属性值改变时该如何处理:
1 //设置键值观察,也就是观察值改变的时候所触发的方法。 2 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ 3 NSString *contextString = [NSString stringWithFormat:@"%@",context]; 4 if ([contextString isEqualToString:@"age"]) { 5 NSLog(@"ageobser%@",[change objectForKey:@"new"]); 6 }else{ 7 NSLog(@"nameobser%@",[change objectForKey:@"new"]);//打印有变化的信息中的new值,也就是变化后的值 8 } 9 10 11 // NSLog(@"%@",change);// 打印所有变化的相关信息 12 13 }
以上键值观察中通过if判断响应函数读入的context生成的字符串contextString去判断是由哪个所观察的键值改变后触发的kvo,然后根据情况进行处理,如果观察的键值多的话可以用switch case语句进行判断执行。还有另一种方法去判断是哪个观察者触发的:
1 if ([keyPath isEqualToString:@"name"]) { 2 NSLog(@"nameobser%@",[change objectForKey:@"new"]); 3 }else{ 4 NSLog(@"ageobser%@",[change objectForKey:@"new"]); 5 }
也就是通过Keypath去判断。因为我们在添加观察者的时候已经设定了不同的keypath有不同的字符串属性。
释放观察者:
1 //移除观察者 2 -(void)dealloc{ 3 [self removeObserver:self forKeyPath:@"name"]; 4 [self removeObserver:self forKeyPath:@"age"]; 5 }
执行结果为;
1 2016-03-28 14:18:39.057 FirstLessonOfUI[2959:66837] nameobsercurrent84 2 2016-03-28 14:18:39.058 FirstLessonOfUI[2959:66837] ageobsercurrent84 3 2016-03-28 14:18:40.558 FirstLessonOfUI[2959:66837] nameobsercurrent36 4 2016-03-28 14:18:40.558 FirstLessonOfUI[2959:66837] ageobsercurrent36 5 2016-03-28 14:18:42.058 FirstLessonOfUI[2959:66837] nameobsercurrent51 6 2016-03-28 14:18:42.059 FirstLessonOfUI[2959:66837] ageobsercurrent51 7 2016-03-28 14:18:43.557 FirstLessonOfUI[2959:66837] nameobsercurrent99 8 2016-03-28 14:18:43.558 FirstLessonOfUI[2959:66837] ageobsercurrent99 9 2016-03-28 14:18:45.058 FirstLessonOfUI[2959:66837] nameobsercurrent99 10 2016-03-28 14:18:45.058 FirstLessonOfUI[2959:66837] ageobsercurrent99