zoukankan      html  css  js  c++  java
  • ios开发UI篇—Kvc简单介绍

    ios开发UI篇—Kvc简单介绍

    一、KVC简单介绍

    KVC key valued coding 键值编码

    KVC通过键值间接编码

      补充:

    与KVC相对的时KVO,即key valued observer 键值观察。监听某一个模型的属性,只要模型属性的值一变化就通知你。

    二、使用KVC

    1.KVC基本使用介绍

    (1)代码示例:

    新建一个命令行项目,用以演示KVC的用法

    完成之后为项目添加一个Person类。

    为Person类添加两个属性(name和age),注意这两个属性的类型。

    1 #import <Foundation/Foundation.h>
    2 
    3 @interface Person : NSObject
    4 @property(nonatomic,copy)NSString *name;
    5 @property(nonatomic,assign) int age;
    6 @end

    在main文件中导入该类,进行编码打印输出,代码如下:

     
     1 #import <Foundation/Foundation.h>
     2 #import "Person.h"
     3 
     4 int main(int argc, const char * argv[])
     5 {
     6 
     7     @autoreleasepool {
     8         
     9         // NSNumber 基本数据类型
    10         // NSValue 结构体
    11         
    12         Person *p1=[[Person alloc]init];
    13         [p1 setValue:@"yangyong" forKeyPath:@"name"];
    14         [p1 setValue:@"23" forKeyPath:@"age"];
    15         
    16         Person *p2=[[Person alloc]init];
    17         [p2 setValue:@"heyun" forKeyPath:@"name"];
    18         [p2 setValue:@"22" forKeyPath:@"age"];
    19         
    20         NSLog(@"%@%@", p1 , [p2  valueForKeyPath:@"name"]);
    21     }
    22     return 0;
    23 }
     

    提示:如果要跟踪打印结果,按照既定格式打印的话,可以重写description方法,这里在Person.m文件中重写了该方法,以便观察打印的输出。

     
    1 #import "Person.h"
    2 
    3 @implementation Person
    4 -(NSString *)description
    5 {
    6     //重写description方法,拼一个字符串,按既定个数输出
    7     return [NSString stringWithFormat:@"<%@:%p>,{name:%@,age:%d}",[self class],self,self.name,self.age];
    8 }
    9 @end
     

    打印结果如下:

    (2)代码说明:

     KVC key valued coding 键值编码

    1)使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。如该程序中的“23”.

    2)KVC按照键值路径取值时,如果对象不包含指定的键值,会自动进入对象内部,查找对象属性

    (3)代码拓展

    问题:如果我们需要只生成name的数组,并打印应该怎么办?

    按照常规的思路,我们可以使用一个for循环来取出数组中对象元素对应属性的值,做法如下:

            //建立一个存储person对象的数组,并打印
            NSArray *persons=@[p1,p2];
            NSLog(@"%@",persons);
            
            NSMutableArray *arrayM=[NSMutableArray array];
            for (Person *p in persons) {
                [arrayM addObject:[p valueForKeyPath:@"name"]];
            }
            NSLog(@"%@",arrayM);
     

    KVC为我们提供了一种更方便的做法:

    提示:KVC按照键值路径取值时,如果对象不包含指定的键值,会自动进入对象内部,查找对象属性

     
         //建立一个存储person对象的数组,并打印
            NSArray *persons=@[p1,p2];
            NSLog(@"%@",persons);
            
            NSMutableArray *arrayM=[NSMutableArray array];
    //        for (Person *p in persons) {
    //            [arrayM addObject:[p valueForKeyPath:@"name"]];
    //        }
            [arrayM addObject:[persons valueForKeyPath:@"name"]];
            NSLog(@"%@",arrayM);
     

    两种方法打印效果一致:

    2.KVC的使用

    (1)说明(KVC在按照键值路径取值时,会自动层层深入,获取对应的键值)

    (2)代码示例:

    在1的基础上,新增加一个类BOOK,为book类设置一个bookname的属性。

    book.h文件的代码如下:

    1 #import <Foundation/Foundation.h>
    2 
    3 @interface Book : NSObject
    4 @property(nonatomic,copy)NSString *bookname;
    5 @end

    同样在book.m文件中重写description方法

     
    1 #import "Book.h"
    2 
    3 @implementation Book
    4 - (NSString *)description
    5 {
    6     return [NSString stringWithFormat:@"<%@,%p>{bookname:%@}", [self class],self,self.bookname];
    7 }
    8 @end
     

    在preson类中增加一个BOOK类的对象属性,让“每个人都拥有一本书”。

     
    1 #import <Foundation/Foundation.h>
    2 @class Book;
    3 @interface Person : NSObject
    4 @property(nonatomic,copy)NSString *name;
    5 @property(nonatomic,assign) int age;
    6 @property(nonatomic,strong)Book *book;
    7 @end
     

    主程序代码:

     
     1 #import <Foundation/Foundation.h>
     2 #import "Person.h"
     3 #import "Book.h"
     4 
     5 int main(int argc, const char * argv[])
     6 {
     7 
     8     @autoreleasepool {
     9         
    10         // NSNumber 基本数据类型
    11         // NSValue 结构体
    12         
    13         Person *p1=[[Person alloc]init];
    14         [p1 setValue:@"yangyong" forKeyPath:@"name"];
    15         [p1 setValue:@"23" forKeyPath:@"age"];
    16         Book *b1 = [[Book alloc] init];
    17         b1.bookname = @"iPhone";
    18         p1.book = b1;
    19         
    20         Person *p2=[[Person alloc]init];
    21         [p2 setValue:@"heyun" forKeyPath:@"name"];
    22         [p2 setValue:@"22" forKeyPath:@"age"];
    23         Book *b2 = [[Book alloc] init];
    24         b2.bookname = @"ios";
    25         p2.book = b2;
    26         
    27         NSLog(@"%@%@", p1 , [p2  valueForKeyPath:@"name"]);
    28         
    29         //建立一个存储person对象的数组,并打印
    30         NSArray *persons=@[p1,p2];
    31         NSLog(@"%@",persons);
    32 
    33         NSArray *arrayM=[persons valueForKeyPath:@"book.bookname"];
    34         NSLog(@"%@",arrayM);
    35     }
    36     return 0;
    37 }
     

    打印结果:

    说明:用KVC取一个嵌套层次很深的路径的时候,只要诶它一个路径就能把想要的属性给拿出来。(.可以理解为路径。一直一直进入)。能够帮助我们很方便的编码。

  • 相关阅读:
    Android游戏开发22:Android动画的实现J2me游戏类库用于Android开发
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第三部分,完整代码)
    使用OGR创建dxf格式矢量数据
    mysql 数据库引擎 MyISAM InnoDB 大比拼 区别
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第二部分)
    mysql 更改数据库引擎
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第一部分)
    android 数字键盘使用
    MySQL Innodb数据库性能实践
    eclipse : Error while performing database login with the driver null
  • 原文地址:https://www.cnblogs.com/asd5551680/p/4068407.html
Copyright © 2011-2022 走看看