KVC(键值编码)(二十五)

kvc的英文全称是key-value-coding,意思就是键值对编码。用普通的话来说,就是kvc就是通过使用键(字符串)来取值的一种编码。是一种间接访问对象属性的机制,不需要调用getter、setter这些存取方法,就可以直接访问对象属性。

我们声明的变量,有可见度。有些私有的,或者受保护的变量,在其他类中,不能直接使用。我们可以通过kvc,用对象在类外部对实例变量进行访问和赋值。不论是什么可见度的实例变量(private,protected,public)。

setValue: forKey:

setValue:@”1111” forKey:@”name”。以此来举例说明,我们的key为name,此时,对象在调用这个方法的时候,会去找我们的声明中,有没有这个name对应的变量或者属性(名字必须是name或者_name)。否则会导致程序找不到匹配的变量,崩溃。

这个方法,优先调用setter方法,即setXxx这种格式的方法,这个set后的Xxx转换成小写后,就可以作为这个key。

如果这时候,找不到匹配的setter方法,就会去找实例变量,并且自动匹配下划线 _ 。(我们在key中加不加下划线 _ 都可以)。如果两者都找不到,就会崩溃。

Person.h


#import <Foundation/Foundation.h>

@interface Person : NSObject{

@private

NSString *_name;

NSString *_sex;

}

- (void)sayHi;

@end

Person.m


#import "Person.h"

@implementation Person

- (void)sayHi{

NSLog(@"%@",_name);

}

@end

main.m


#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

@autoreleasepool {

Person *p1 = [[Person alloc]init];

//setValue:forKey:

//优先调用setter方法,即:setXxx:,这个set后面的 Xxx 就可以作为key。

//其次,set方法没有找到,就去找实例变量。并且自动识别下划线。(我们在key里加不加下划线都可以识别名字)。如果名字不一样,崩溃

p1->_name;

//kvc第一个方法:

[p1 setValue:@"123" forKey:@"name"];

NSLog(@"%@",[p1 valueForKey:@"name"]);

}

return 0;

}

解释:

[p1 setValue:@"123" forKey:@"name"];p1在设置key为name的变量的值为“123”,此时就回去找setter方法,发现没有定义setter方法,就回去实例变量中匹配,发现有一个_name,与之匹配,则对 _name进行赋值。

valueForKey:用键取值

通过键来取value,优先调用getter方法,取值,即形如我们定义的getter方法的方法xxx,((返回值)方法名,这样的方法就是形如getter方法。方法名就作为key),如实没有找到getter方法,就会去找实例变量,并能识别下划线 _。


NSLog(@"%@",[p1 valueForKey:@"name"]);

解释:去找name的getter方法,发现没找到,就去找实例变量,匹配到了,就可以取到值。

valueForKey:不仅可以取到变量值,还能用方法名作为key去找一个方法,然后执行。

Person.h


#import <Foundation/Foundation.h>

@interface Person : NSObject{

@private

NSString *_name;

NSString *_sex;

}

- (void)sayHi;

@end

Person.m


#import "Person.h"

@implementation Person

- (void)sayHi{

NSLog(@"%@",_name);

}

- (void)setLol:(NSString *)lol{

NSLog(@"%@",lol);

}

//没有找到对应key

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

NSLog(@"没有key:%@,value:%@",key,value);

}

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

NSLog(@"没有 key :%@",key);

return nil;

}

@end

main.m


[p1 sayHi];

[p1 valueForKey:@"sayHi"];

[p1 setValue:@"德玛西亚" forKey:@"Lol"];//2015-04-22 16:08:00.048 OClesson8_KVC[2113:121073] 德玛西亚

解释:

在.h中声明了sayHi方法,在.m中实现sayHi,此时在main函数中用p1对象调用valueForKey:@"sayHi",就会把这个sayHi字符串去匹配,发现匹配了一个方法,此时就会去调用这个方法,执行。

在.m中实现了Lol:这个方法,在main方法中,对象p1调用了setValue:@"德玛西亚" forKey:@"Lol"方法,就把Lol作为key去匹配,发现匹配了setLol:方法,此时就会把value当作参数传进去,执行setLol:方法。

从父类继承过来的私有,受保护的实例变量,也可以用kvc访问。

setValue: forKeyPath:按照路径设置值

valueForKeyPath: 按照路径取值

若实例变量中有我们自定义的类,这个自定义的类中有另外的实例变量。此时要想访问实例变量为自定义类中的实例变量,就需要kvc按路径访问。

setValue:forUndefinedKey:设置值匹配不到key的处理

valueForUndefinedKey: 取值匹配不到key的处理

如果在按key访问变量或方法的时候,匹配不到所给的字符串(也就是key),需要加上setValue:forUndefinedKey(设置值)或者valueForUndefinedKey(取值)进行相应的处理,防止程序崩掉。

setValuesForKeysWithDictionary:按字典设置值

当有很多个值得时候,我们可以一次性赋值,就是用字典来赋值。

Person.h(父类)


#import <Foundation/Foundation.h>

@interface Person : NSObject{

@private

NSString *_name;

NSString *_sex;

}

- (void)sayHi;

@end

Person.m(父类实现)


#import "Person.h"

@implementation Person

- (void)sayHi{

NSLog(@"%@",_name);

}

- (void)setLol:(NSString *)lol{

NSLog(@"%@",lol);

}

//没有找到对应key

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

NSLog(@"没有key:%@,value:%@",key,value);

}

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

NSLog(@"没有 key :%@",key);

return nil;

}

@end

Student.h(继承于Person类)


#import "Person.h"

@class Book;

@interface Student : Person{

Book *_book;

}

@end

Student.m


#import "Student.h"

#import "Book.h"

@implementation Student

@end

Book.h(继承于Student类)


#import <Foundation/Foundation.h>

@interface Book : NSObject{

NSString *_bookName;

}

@end

Book.m


#import "Book.h"

@implementation Book

@end

main.m


#import <Foundation/Foundation.h>

#import "Person.h"

#import "Student.h"

#import "Book.h"

int main(int argc, const char * argv[]) {

@autoreleasepool {

Person *p1 = [[Person alloc]init];

Student *s1 = [[Student alloc]init];

//从父类继承的私有实例变量,也可以用kvc访问。

[s1 setValue:@"22222" forKey:@"name"];

NSLog(@"%@",[s1 valueForKey:@"name"]);//2015-04-22 16:21:33.162 OClesson8_KVC[2186:125614] 22222

Student *s2 = [[Student alloc]init];

Book *b1 = [[Book alloc]init];

//        [b1 setValue:@"红楼梦" forKey:@"bookName"];

[s2 setValue:b1 forKey:@"book"];

[s2 setValue:@"红楼梦" forKeyPath:@"book.bookName"];//点 . 不是点语法,是路径的意思。

NSLog(@"%@",[s2 valueForKeyPath:@"book.bookName"]);//2015-04-22 16:32:49.975 OClesson8_KVC[2236:129639] 红楼梦

//      //设置值没有对应的key,在person.m中写一个undifind

//    [p1 setValue:@"12131313" forKeyPath:@"num"];//2015-04-22 16:54:24.955 OClesson8_KVC[2324:135915] 没有key:num,value:12131313

//        //取值没有对应的key,在person.m中写一个undifind

//        [p1 valueForKeyPath:@"num"];//2015-04-22 16:56:22.108 OClesson8_KVC[2348:136844] 没有 key :num

NSDictionary *dict = @{@"name":@"Mick",@"sex":@"男"};

//一次性赋多个值,在网络解析中常用。

[p1 setValuesForKeysWithDictionary:dict];

}

return 0;

}

时间: 2024-09-27 06:30:23

KVC(键值编码)(二十五)的相关文章

Objective-C(十七、KVC键值编码及实例说明)——iOS开发基础

结合之前的学习笔记以及参考<Objective-C编程全解(第三版)>,对Objective-C知识点进行梳理总结.知识点一直在变,只是作为参考,以苹果官方文档为准~ 十七.键值编码 KVC 关于KVC的知识点将通过下列例子来展开说明: Person.h文件,Person类拥有name和age两个成员变量 @interface Person : NSObject { @private NSString *_name; NSInteger _age; } - (void)setAge:(NSIn

KVC - 键值编码

[基本概念] 1.键值编码是一个用于间接访问对象属性的机制,使用该机制不需要调用存取方法和变量实例就可访问对象属性. 2.键值编码方法在OC非正式协议(类目)NSKeyValueCoding中被声明,默认的实现方法由NSObject提供. 3.键值编码支持带有对象值的属性,同时也支持纯数值类型和结构.非对象参数和返回类型会被识别并自动封装/解封. [键值访问] 键值编码中的基本调用包括-valueForKey: 和 -setValue:forkey: 这两个方法,它们以字符串的形式向对象发送消息

关于KVC键值编码

转载自http://www.tuicool.com/articles/2aYfy2 Key-value coding,它是一种使用字符串标识符,间接访问对象属性的机制,而不是直接调用getter 和 setter方法.通常我们使用valueForKey 来替代getter 方法,setValue:forKey来代替setter方法. 首先来看一看KVC与setter,getter方法赋值的区别 Persion *person = [ [Person alloc] init ]; //不使用KVC

ios中键值编码kvc和键值监听kvo的特性及详解

总结: kvc键值编码  1.就是在oc中可以对属性进行动态读写(以往都是自己赋值属性)           2. 如果方法属性的关键字和需要数据中的关键字相同的话                  3. 动态设置:setValue:属性值 forKey:属性名(用于简单的路径)/setValue:属性值 forKeyPath:属性名(用于复杂的路径)kvo键值监听  永久性的监听item属性值的改变,如果改变就从新设置             1.监听方法:[addObserver:self

IOS开发之旅-KVC【键值编码】

在日常开发中,读取修改对象的属性值时,通常是点调用对应的属性进行相关操作.另外一种方式是通过键值编码,简称KVC,在键值编码中主要使用以下方法 /* Given a key that identifies an attribute or to-one relationship, return the attribute value or the related object. Given a key that identifies a to-many relationship, return a

OC8-属性 KVC是键值编码

1.属性,是oc提供的一种快速的模式化的创建实例变量的方式. (1)属性是通过@property标记的, (2)属性会在背后,默默的帮我们做set和get方法 2.属性做的工作 (1)创建一个实例变量,名字是下划线加属性名, (2)帮我们自动get和setter 的方式,创建一组方法, 3.点语法,点语法是专门为了setter 和getter 方法配备的一种语法糖.会自动根据语法和语境调用是哪一种方法, (1) (.)其实就是转换成了getter 和setter 方法,p.hobby.lengt

iOS学习笔记(6)键值编码——KVC

在KVC编程方式中,无论调用setValue:forKey:方法,还是调用valueForKey:方法,都是通过NSString对象来指定被操作属性,其中forKey:标签用户传入属性名的. 对于setValue:属性值[email protected]“name”;代码,底层的执行机制如下. (1)程序优先考虑调用“setName:属性值;”代码通过setter方法完成设置. (2)如果该类没有setName:方法,KVC机制会搜索该类名为_name的成员变量,无论该成员变量是在类接口部分定义

【OC学习-31】利用KVC即键值编码来访问一些对象的属性,尽管这些属性是私有的

最简单的想法是我们创建一个对象,然后利用某些方法给这个对象赋值,然后再用某些方法调用这个值.当然这种描述很类似于字典的键值概念,确实今天学习的就是这样一种方法:KVC,Key-Value coding键值编码. (1)简单的KVC 创建一个Book类,在Book.h里写一个私有的实例变量name,然后再main.m里创建一个book1对象,再给这个book1对象的私有变量name赋值,然后再调用这个值.神奇的地方就在这里:这种方法根本不管这个实力变量是private还是public.呃,Book

QT开发(二十五)——QT模板库

QT开发(二十五)--QT模板库 一.QTL模板库简介 QT模板库(QT Template Library 简称QTL)是一套提供对象容器的模板. QTL提供了对象的链表.对象的矢量(动态数组).从一个类型到另一个类型的映射(或称为字典)和相关的迭代器和算法.容器是包含和管理其它对象的一个对象,并且提供迭代器对被包含的对象进行访问. 1.QT容器类简介 容器是能够在内存中存储其他特定类型的对象的对象,一般是通用的模板类.QT提供了自己的一套容器类,即在QT的应用程序中,可以使用标准C++的STL

Java进阶(二十五)Java连接mysql数据库(底层实现)

Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜索.特将之前使用的方法做一简单的总结.也能够在底层理解一下连接数据库的具体步骤. 实现 首先需要导入相关的jar包,我使用的为:mysql-connector-java-5.1.7-bin.jar. 下面来看一下我所使用的数据库连接方法类: MysqlUtil.java package cn.edu