iOS开发iOS基础面试iOS 原理

KVC、KVO探识(一)KVO和KVO的详细使用

2016-03-25  本文已影响687人  Peak_One
前言

最近一直在做原型图,中间有两天没有写简书了。感觉心里面特别不是滋味。所以今天好不容易忙中偷闲,所以今天必须写几篇简书,安慰一下自己的内心。于是今天给大家分享一下KVC和KVO的简单用法,随后会更加深层次的去写一系列的简书,去深层次的讲解KVC和KVO。

KVC用法

KVC也就是key-value-coding(键值编码),简而言之就是通过key值去进行赋值和取值。主要是是操作对象的属性。以下是几个常用的方法:

几种方法的详尽用法

例如:生成一个这样子的对象Person
person.h

@class Car;
@interface Person : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,strong)Car *car;
@end

Car.h

@interface Car : NSObject
@property (nonatomic,strong) NSNumber *price;
@end

在ViewController.m中调用
ViewController.m

- (void)viewDidLoad {
      [super viewDidLoad];
      Person *person=[[Person alloc]init];
      [person setValue:@"lxh" forKey:@"name"];
      float price=100.0;
      Car *car=[[Car alloc]init];
      person.car=car;
      [person setValue:[NSNumber numberWithFloat:price] forKeyPath:@"car.price"];
      NSLog(@"%@",person.name);

      NSLog(@"%f",car.price.floatValue);
}

有几个小点,我也是在敲代码的时候发现的。

KVC和对象的setter、getter方法的区别

一般情况下,KVC和setter、getter应该说都能达到对对象属性的赋值,并且KVC操作也是去调用的setter方法和getter方法(针对一些已经在.h中声明的属性而言)。但是对于一些私有属性,那么这个时候setter、getter方法就没有用了,这个时候KVC却能发挥重要优势。
例如:在Person.m中
#import "Person.h"
@implementation Person
{
NSInteger _height;
}
@end
此时你会发现setter、getter已经无能为力了,但是KVC去可以实现赋值、取值

[p setValue:@170 forKey:@"height"];
key和keyPath的区别

keyPath方法是集成了key的所有功能,也就是说对一个对象的一般属性进行赋值、取值,两个方法是通用的,都可以实现。但是对对象中的对象进的属性行赋值,只有keyPath能够实现。

setValuesForKeysWithDictionary:的巧妙使用(字典转模型)
-(instancetype)initWithDict:(NSDictionary *)dict{
         if (self = [super init]) {
               [self setValuesForKeysWithDictionary:dict]; 
          } 
         return self;
}
注意点:
KVO的用法

KVO也就是key-value-observing(即键值观察),利用一个key来找到某个属性并监听其值得改变。用法如下:

//让对象b监听对象a的name属性
//options属性可以选择是哪个
 /* NSKeyValueObservingOptionNew =0x01, 新值 
  * NSKeyValueObservingOptionOld =0x02, 旧值 
  */ 
[a addObserver:b forKeyPath:@"name"options:kNilOptionscontext:nil]; 
a.name = @"zzz";
#pragma mark - 实现KVO回调方法
/* * 当对象的属性发生改变会调用该方法
    * @param keyPath 监听的属性 
    * @param object 监听的对象 
    * @param change 新值和旧值 
    * @param context 额外的数据 
*/
- (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary<NSString *,id>*)change context:(void *)context{ 
    NSLog(@"%@的值改变了,",keyPath); 
    NSLog(@"change:%@", change);
}
//最后不要忘记了,去移除observer
- (void)dealloc{ 
       [a removeObserver:b forKeyPath:@"name"];
  }
KVO底层(这部分涉及到了runtime,关于isa指针,会在随后的简述中介绍)

当一个类的属性被观察的时候,系统会通过runtime动态的创建一个该类的派生类,并且会在这个类中重写基类被观察的属性的setter方法,而且系统将这个类的isa指针指向了派生类,从而实现了给监听的属性赋值时调用的是派生类的setter方法。重写的setter方法会在调用原setter方法前后,通知观察对象值得改变。
  具体实现图如下,这里我拿的是iOS程序猿的图,借用一下应该没关系吧?


今天仅仅是KVO和KVC的简单的用法的介绍,随后会更加深层次的进行介绍,敬请期待.....

上一篇 下一篇

猜你喜欢

热点阅读