zoukankan      html  css  js  c++  java
  • IOS 高级开发 KVC(一)

      熟练使用KVC 可以再开发过程中可以给我们带来巨大的好处,尤其是在json 转模型的时候,KVC让程序员摆脱了繁琐无营养的代码堆积。减少代码量就是减少出错的概率。KVC 用起来很灵活,这种灵活的基础是严格的命名要求。这种命名要求其实是一种约定。再程序的世界里,约定的作用远远大于开发本身,良好的约定可以使程序员摆脱很多判断,也减少了错误。KVC有如下几点作用:

    1)、直接赋值

    使用KVC 可以对对象的某个属性进行赋值。假定现在我们有一个Person 类,类中包含两个属性:一个是只读的name 属性,一个是Number类型的age属性。

    //
    //  Person.h
    //  KVC
    //
    //  Created by 邓竹立 on 15-4-24.
    //  Copyright (c) 2015年 GiveMeFive. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @property(nonatomic,copy,readonly)NSString* name;
    
    @property(nonatomic,assign)NSNumber *age;
    
    @end

    当我们定义了属性的时候,系统就为我们自动的生成了setter 和getter 方法。我们可以通过setter 和getter方法,或读取或写入数值。当然我们也可以用KVC 的方式进行读写数据。先看一下代码,然后我们再简述一下需要注意的问题。

    #import "ViewController.h"
    #import "Person.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        Person *person=[[Person alloc] init];
        
        [person setValue:@"25" forKey:@"age"];
        [person setValue:@"皮拉夫大王" forKey:@"name"];
        
        NSLog(@"person 的名字是%@",person.name);
        NSLog(@"person 的年领是%@",[person valueForKey:@"age"]);
    }
    
    
    @end

    2015-04-24 20:40:13.286 KVC[6208:218095] person 的名字是皮拉夫大王

    2015-04-24 20:40:13.287 KVC[6208:218095] person 的年领是25

    如果你没有接触过KVC 的话,你大概会想:我擦,大王的脑子坏掉了吧?只读的属性怎么可以赋值?!还有age属性明明是NSNumber类型的,怎么可以把字符串赋给它?!没错,这就是我想说的,KVC 不但能够赋值,而且还能破坏只读的特性。当然这只是我们需要注意的一个细节,更重要的是KVC 有自动装箱(自动类型转换)的功能,我们不需要去转换类型了。由于开发过程中数据领域是字符串的天下,所以这个自动装箱的功能的确是极好的。

    2)、支持键值路径

    什么叫支持键值路径?说白了就是支持嵌套。假如现在有一个书籍类,类中包含了书籍的名称name。书籍可以被Person所拥有(就是可以作为person的属性)

    #import <Foundation/Foundation.h>
    
    @interface Book : NSObject
    
    @property(nonatomic,copy)NSString* name;
    
    @end

    那么我们就可以这样来用

        Person *person=[[Person alloc] init];
        Book *myBook=[[Book alloc] init];
        person.book=myBook;
        
        [person setValue:@"程序员摊煎饼指南" forKeyPath:@"book.name"];
        
        NSLog(@"%@",[person valueForKeyPath:@"book.name"]);

    这里的key直接使用点局分开就好了,注意一下:这里使用的时keyPath,当然在   “ 1)属性赋值”   中我们也可以使用keyPath,只不过再不必要的情况下使用keyPath会浪费性能而已。这里没啥可说的了,说多了都对不起我一度5毛的电费。

    3)支持操作符

    假如我们有10个字符串,我们想求出这10个字符串的总长度,我们可以使用KVC提供的操作符。

    NSArray *books=@[@"鸟哥烧烤私房菜",@"程序员摊煎饼宝典",@"麻辣烫基础教程"];
    NSLog(@"%@",[books valueForKeyPath:@"@sum.length"]);

    这里的@sum 是KVC 提供的,不是我们写的。像这样的函数共有5个@avg,@count,@max,@min,@sum。我们直接用就可以了。但是据说效率比用for循环慢。我没有测试过,感兴趣的话你可以测试一下。

    4)错误拦截

    对于我们前端程序员来说,后端程序员有时也是一个troubleMaker。他总是给你传递一些很奇怪的东西。比如给你传递一个id 属性,或者什么都不给你传。如果有这样一个json文件 {“id”:"1"}。这是逼着我们把id作为数据模型的一个属性的节奏啊!!老夫不愿意啊!尽管作为属性也不会报错。屈服?还是抗争?这是一个问题。但是好在前辈们已经给了我们答案。假如我们有一个Model类,类中的whoCare属性就是本应命名为id 的属性。我们还写了一个字典转模型的初始化方法。

    @interface Model : NSObject
    
    @property(nonatomic,strong)id whoCare;
    
    -(instancetype)initWithDict:(NSDictionary *)dict;
    
    @end

    那么我们可以在.m文件中重写 -(void)setValue:(id)value forUndefinedKey:(NSString *)key 方法。这个方法会在字典转模型时,系统找不到同名的属性时调用。所以我们可以再这个方法中进行错误拦截,并进行赋值操作,这样就不会报错了。

    #import "Model.h"
    
    @implementation Model
    
    
    -(instancetype)initWithDict:(NSDictionary *)dict
    {
        if (self=[super init])
        {
            //忘了介绍了 字典转模型的常用语句
            [self setValuesForKeysWithDictionary:dict];
        }
        return self;
    }
    
    -(void)setValue:(id)value forUndefinedKey:(NSString *)key
    {
        if ([key isEqualToString:@"id"])
        {
            self.whoCare=value;
        }
    }
    
    @end

    写好了模型类,我们可以来测试一下。

    #import "Model.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        NSDictionary *dict=@{@"id":@"1"};
        
        Model *model=[[Model alloc] initWithDict:dict];
        
        NSLog(@"%@",model.whoCare);
    }
    
    
    @end

    程序没有崩溃,而且赋值成功。不信你看打印信息

    2015-04-24 21:12:00.676 KVC[6393:228807] 1

     

     

  • 相关阅读:
    移动硬盘插入电脑后检测到却不显示如何解决?
    Js求角度、三角形、弧度计算
    Python之常用模块(一)
    PostgreSQL中的MVCC 事务隔离
    520了,用32做个简单的小程序
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    MySQL 返回未包含在group by中的列
    《Mysql日志备份/恢复》大型详细攻略两万字图解(史上最详细,多图)
    年轻就该多尝试,教你20小时Get一项新技能
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
  • 原文地址:https://www.cnblogs.com/dengzhuli/p/4454516.html
Copyright © 2011-2022 走看看