首页 > KVC 和 KVO

KVC 和 KVO

KVC 键值编码



    全称是Key-value coding,翻译成键值编码。它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制。

    

    1.通过key(成员变量的名称)设置value(成员变量的值)

    - (void)setValue:(id)value forKey:(NSString *)key;



    2.通过keyPath(成员变量的路径)设置value(成员变量的值)

    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;



    3.通过key(成员变量的名称)获取value(成员变量的值)

    - (id)valueForKey:(NSString *)key;



    4.通过keyPath(成员变量的路径)获取value(成员变量的值)

    - (id)valueForKeyPath:(NSString *)keyPath;



    5.重写此方法防止出现未定义key值的时候出现崩溃

    - (void)setValue:(id)value forUndefinedKey:(NSString *)key;



    6.重写此方法防止获取未定义key值的时候出现崩溃

    - (id)valueForUndefinedKey:(NSString *)key;



    7.通过键值对的形式给成员变量赋值

    - (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

举个简单的例子:一个对象拥有某些属性。比如说,一个 Person 对象有一个 perName,uid,perID和一个 sex 属性。以 KVC 说法,Person 对象分别有一个 value 对应他的 perName,uid,perID和一个 sex 的 key。 key 只是一个字符串,它对应的值可以是任意类型的对象。从最基础的层次上看,KVC 有两个方法:一个是设置 key 的值,另一个是获取 key 的值。

#import @interface Person : NSObject@property (nonatomic,copy)NSString *perName;
@property (nonatomic,copy)NSString *sex;
@property (nonatomic,copy)NSString *uid;
@property (nonatomic,copy)NSString *perID;@end

 

#import "Person.h"@implementation Person-(void)setValue:(id)value forKey:(NSString *)key{//判断是否为NSNumber类型if ([value isKindOfClass:[NSNumber class]]) {[self setValue:[NSString stringWithFormat:@"%@",value] forKey:key];}else {//调用父类的方法[super setValue:value forKey:key];}}-(void)setValue:(id)value forUndefinedKey:(NSString *)key{//手动赋值if ([key isEqualToString:@"id"]) {[self setValue:value forKey:@"perID"];}else{NSLog(@"未定的key值:%@",key);}}-(id)valueForUndefinedKey:(NSString *)key{NSLog(@"未找到key:%@",key);return nil;
}- (NSString *)description
{return [NSString stringWithFormat:@"name = %@,sex = %@,ID= %@,perID = %@", _perName,_sex,_uid,_perID];
}@end

 

#import 
#import "Person.h"int main(int argc, const char * argv[]) {@autoreleasepool {Person *per = [Person new];//模拟返回的服务器数据NSDictionary *dictionary = @{@"perName":@"小红",@"sex":@"女",@"uid":[NSNumber numberWithInteger:888],@"id":@"12345"};//通过KVC一次性给3个成变量赋值[per setValuesForKeysWithDictionary:dictionary];NSLog(@" %@",per);}return 0;
}

 

 



========================================

KVO 键值观察者模式



    全称是Key-value observing,翻译成键值观察。提供了一种当其它对象属性被修改的时候能通知当前对象的机制



    1.添加观察者

    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;



    2.对象被释放之前,要移除观察者,通常写在dealloc函数当中

    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;



    3.当属性值发生变化之后的回调函数

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

监听一个contentSize的例子:点击一个加号会添加10个cell

 

#import "ViewController.h"@interface ViewController ()@property (nonatomic,assign)NSInteger count;//控制行数
@property (nonatomic,assign)CGSize recordSize;//记录当前UITableView的ContentSize;
@property (weak, nonatomic) IBOutlet UITableView *myTableView;@end@implementation ViewController-(void)dealloc{//移除观察者[self.myTableView removeObserver:self forKeyPath:@"contentSize"];}- (void)viewDidLoad {[super viewDidLoad];//观察myTableView的contentSize[self.myTableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];//设置导航栏右侧按钮self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"+" style:UIBarButtonItemStylePlain target:self action:@selector(add)];self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"__" style:UIBarButtonItemStylePlain target:self action:nil];}//增加行数
-(void)add{self.count += 10;//刷新UI[self.myTableView reloadData];//self.recordSize = self.myTableView.contentSize;//NSLog(@"%f",self.recordSize.height);
}
#pragma mark- KVO回调方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{//判断是否为对应的观者属性if ([keyPath isEqualToString:@"contentSize"] && object == self.myTableView) {NSLog(@"%@ %f",change, self.recordSize.height);//记录变化之后的contentSizeself.recordSize = [change[@"new"] CGSizeValue];}}#pragma mark- UITableView代理
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{return self.count;
}-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];if (!cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];}cell.textLabel.text = @"哈哈";return cell;}@end

 如果对你有帮助,请关注我哦!

转载于:https://www.cnblogs.com/laolitou-ping/p/6256486.html

更多相关:

  • 前言 近期在做on nvme hash引擎相关的事情,对于非全序的数据集的存储需求,相比于我们传统的LSM或者B-tree的数据结构来说 能够减少很多维护全序上的计算/存储资源。当然我们要保证hash场景下的高写入能力,append-only 还是比较友好的选择。 像 Riak的bitcask 基于索引都在内存的hash引擎这种,...

  • 前言 最近在读 MyRocks 存储引擎2020年的论文,因为这个存储引擎是在Rocksdb之上进行封装的,并且作为Facebook 内部MySQL的底层引擎,用来解决Innodb的空间利用率低下 和 压缩效率低下的问题。而且MyRocks 在接入他们UDB 之后成功达成了他们的目标:将以万为单位的服务器集群server个数缩减了一...

  • 参考自:  https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html 1、maven依赖

    springboot redis配置

    1、引入maven依赖 org.springframework.bootspring-boot-starter-data-redis   2、redis连接配置 spring:redis:h...

  • json 键值对增加、删除 obj.key='value'; // obj.key=obj[key]=eval("obj."+key); delete obj.key; vue中新增和删除属性 this.$set(object,key,value) this.$delete( object, key ) 触发视图更新 遍历键值 for...

  • //检查更新页面- (void)Renew{        NSDictionary *infoDic = [[NSBundle mainBundle]infoDictionary];        NSString *version = [infoDic valueForKey:@"CFBundleShortVersionStrin...

  • * 苹果的"生态圈",钥匙串访问,使用 AES 256 加密算法,能够保证用户密码的安全 * 钥匙串访问SDK,是苹果在 `iOS 7.0.3` 版本以后公布的 * 钥匙串访问的接口是纯 C 语言的,但是,网络上有框架把它封装成 OC 的,使用相当简单! * 钥匙串访问的密码保存在哪里?     * 只有苹果知道!是为了进一步保障...

  • IOS开发数据库篇—SQLite模糊查询 一、示例 说明:本文简单示例了SQLite的模糊查询 1.新建一个继承自NSObject的模型 该类中的代码: 1 // 2 // YYPerson.h 3 // 03-模糊查询 4 // 5 // Created by apple on 14-7-27. 6 // C...

  • 因为函数参数是按值传递的,所以要想改变变量,必须传递地址。 二级指针实际上就是指针变量的地址,如果传递二级指针,函数声明必须写**。 (void**)&必须是本质上就是指针变量的地址才可以做这样的转换,并不是说把一个一级指针也可以转换,void**的本质是标识一个二级指针。 &data就是(默认数据类型 **)&data,(void...

  • 文章目录1. 解决问题2. 应用场景3. 实现如下:C++实现C语言实现4. 缺点 1. 解决问题 在工厂方法模式中,我们卖衣服。此时我们为每一种衣服创建不同的工厂,帽子有一个工厂专门创建,裤子有一个工厂专门创建,T恤有一个工厂专门创建。这样的方式保证了代码设计的开闭原则(对扩展开发,对修改关闭),解决了简单工厂模式中暴露的...

  • 转载于:http://blog.csdn.net/u012819339/article/details/50654764   实体作品请参看优酷视频。 若以上链接点击无效请把该链接地址复制到浏览器地址栏 http://v.youku.com/v_show/id_XODYzODczNzQ4.html 说明: 该作品为arvik于2014...

  • - (void)viewDidLoad {[super viewDidLoad];NSLog(@"我在玩手机");NSLog(@"手机没电了");[self chargeMyIphone:^{NSLog(@"出门逛街");}];NSLog(@"我在看电视"); }-(void)chargeMyIphone:(void(^)(void...

  • http://stackoverflow.com/questions/150446/how-do-i-detect-when-someone-shakes-an-iphone 我的实现(基于Eran Talmor): 没必要application.applicationSupportsShakeToEdit = YES; Set th...