kvc


1、键值编码的基本概念和用法


键值编码的基本概念


1. 键-值编码是一个用于间接访问对象属性的机制,使用该机制不需要调用存取方法和变量实例就可访问对象属性。


2. 键-值编码方法在Objective-C非正式协议(类目)NSKeyValueCoding中被声明,默认的实现方法由NSObject提供。


3. 键-值编码支持带有对象值的属性,同时也支持纯数值类型和结构。非对象参数和返回类型会被识别并自动封装/解封。




KVC的基本用法




设置和访问


键/值编码中的基本调用包括-valueForKey:和-setValue:forkey:这两个方法,它们以字符串的形式向对象发送消息,字符串是我们关注属性的关键。


Book *book = [[Book alloc] init];
NSMutableString *name = [[NSMutableString alloc] initWithFormat:@"jack"];
[book setValue:name forKey:@"name"];
NSLog(@"jack name : %@", [book valueForKey:@"name"]);






是否存在setter、getter方法,如果不存在,它将在内部查找名为_key或key的实例变量。






通过KVC,可以获取不存在getter方法的对象值,无需通过对象指针直接访问。
这里我们需要注意,当我们通过setValue:forKey:设置对象的值,或通过valueForKey来获取对象的值时,如若对象的实例变量为基本数据类型时
(char、int、float、BOOL),我们需要对数据进行封装。














路径与一对多的关系


路径


除了通过键设置值外,键/值编码还支持指定路径,像文件系统一样。用“点”号隔开。


[book setValue:@"比尔" forKeyPath:@"author._name"];
[book valueForKeyPath:@"realtiveBooks.price"]










一对多的关系


如果向NSArray请求一个键值,它实际上会查询数组中的每个对象来查找这个键值,然后将查询结果打包到另一个数组中并返回给你。


NSArray *booksArray = [NSArray arrayWithObjects:book1, book2, nil];
[book setValue:booksArray forKey:@"relativeBooks"];
NSLog(@"books 2: %@", [book valueForKeyPath:@"relativeBooks.price"]);








实现简单的运算


KVC的简单运算


此外,还可以应用一些字符做简单运算。sum、min、max、avg、count


NSString *count = [book valueForKeyPath:@"relativeBooks.@count"];
NSLog(@"count : %@", count);
NSString *sum = [book valueForKeyPath:@"relativeBooks.@sum._price"];
NSLog(@"sum : %@", sum);
NSString *avg = [book valueForKeyPath:@"relativeBooks.@avg._price"];
NSLog(@"avg : %@", avg);
NSString *min = [book valueForKeyPath:@"relativeBooks.@min._price"];
NSLog(@"min : %@", min);
NSString *max = [book valueForKeyPath:@"relativeBooks.@max._price"];
NSLog(@"max : %@", max);










示例:


打开xcode 


点击  create  a  new  xcode  project


点击  左侧  Application  选择右侧中的 Command Line  Tool(相当于windows下的command)


         ---  next


  product Name:BookKVCDemo
  
  Company identifier:com.imti


  type: foundation  是一个framework




  取消选择 use Automatic  Reference  Counting




        ---  next




        ---  create




new  file...    


           name:Author
           subclass:  NSObject




Author.h


#import <Foundation/Foundation.h>


@interface Author : NSObject {
@private
    NSString *_name;
}


@end






new  file...    


           name:Book
           subclass:  NSObject






Book.h


#import <Foundation/Foundation.h>
#import "Author.h"


@interface Book : NSObject {
@private
    NSString *_name;
    Author *_author;    //书的作者
    NSArray *_relativeBooks; //相关的书籍
    
    float price;        //书的价格
}


@end






打开  main.m  加入


#import "Book.h"




在加入




    @autoreleasepool {
        Book *book = [[Book alloc] init];
        Author *author = [[Author alloc] init];
        [author setValue:@"jack" forKey:@"_name"];
        [book setValue:[NSNumber numberWithFloat:12.6] forKey:@"price"];
        
        NSNumber *price = [book valueForKeyPath:@"price"];
        NSLog(@"%@",price);
        
        //键值访问
        [book setValue:@"ipad develper" forKey:@"name"];
        [book setValue:author forKey:@"_author"];
        
    
   }


运行 




KVC的缺点,你感觉到了吗?  


   如果属性名字写错了 编译不会报错 但运行的时候会报错








加入 


        //路径访问
        [book setValue:@"tom" forKeyPath:@"author.name"];
        NSString *authorName = [book valueForKeyPath:@"_author._name"];
        NSLog(@"%@",authorName);




运行




加入




//一对多的关系
        NSMutableArray *releBooks = [NSMutableArray arrayWithCapacity:3];
        for (int i=0; i<3; i++) {
            Book *book = [[Book alloc] init];
            NSString *name = [NSString stringWithFormat:@"job_%d",i];
            [book setValue:name forKey:@"_name"];
            
            [book setValue:@(12+i) forKey:@"price"];
            [releBooks addObject:book];
            [book release];
        }
        [book setValue:releBooks forKey:@"_relativeBooks"];
        NSArray *names = [book valueForKeyPath:@"_relativeBooks._name"];
        NSLog(@"%@",names);


运行




 将
        NSArray *names = [book valueForKeyPath:@"_relativeBooks._name"];
        NSLog(@"%@",names);


 注释掉加入




       NSArray *names = [releBooks valueForKeyPath:@"_name"];
       NSLog(@"%@",names);




运行




 加入  


        //运算, 运算的字段必须是数值类型NSNumber或者基本数据类型,计算的结果是NSNumber
        //运算关键字sum、min、max、avg、count
        NSNumber *sum = [book valueForKeyPath:@"_relativeBooks.@avg.price"];
        NSLog(@"sum: %@",sum);




 运行
















课堂练习1


定义一个Person对象,他叫乔布斯,他有许多苹果设备:
1个macbook,价格8000
1个iPhone, 价格5000
1个iPad, 价格3800
使用kvc为Person设置名字, 使用kvc计算乔布斯所有设备的总价。










示例:


打开xcode 


点击  create  a  new  xcode  project


点击  左侧  Application  选择右侧中的 Command Line  Tool(相当于windows下的command)


         ---  next


  product Name:PersonKVC
  
  Company identifier:com.imti


  type: foundation  是一个framework




  取消选择 use Automatic  Reference  Counting




        ---  next




        ---  create




new  file...    


           name:Person
           subclass:  NSObject






 Person.h


#import <Foundation/Foundation.h>


@interface Person : NSObject {
@private
    NSString *name;
    NSArray *apples;
}


@end








new  file...    


           name:AppleDevice
           subclass:  NSObject






AppleDevice.h




#import <Foundation/Foundation.h>


@interface AppleDevice : NSObject {
@private
    NSString *_name;
    float _price;
}


@end








 main.m




加入




 #import "Person.h"
 #import "AppleDevice.h"




在加入




  @autoreleasepool {
        AppleDevice *mac = [[AppleDevice alloc] init];
        [mac setValue:@"macbook" forKey:@"_name"];
        [mac setValue:@8000 forKey:@"_price"];


        AppleDevice *iphone = [[AppleDevice alloc] init];
        [iphone setValue:@"iphone" forKey:@"_name"];
        [iphone setValue:@5000 forKey:@"_price"];
        
        AppleDevice *ipad = [[AppleDevice alloc] init];
        [ipad setValue:@"ipad" forKey:@"_name"];
        [ipad setValue:@3800 forKey:@"_price"];
        
        NSArray *apples = @[mac,iphone,ipad];
        [ipad release];
        [mac release];
        [iphone release];
        
        Person *p = [[Person alloc] init];
        [p setValue:@"乔布斯" forKey:@"name"];
        [p setValue:apples forKey:@"apples"];
        
        NSNumber *sum = [p valueForKeyPath:@"apples.@sum._price"];
        NSLog(@"%@",sum);
        
        [p release];
        
    }









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值