zoukankan      html  css  js  c++  java
  • 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:(NSInteger)age;
     @end

    Person.m实现了该方法

     @implementation Person
    
     - (NSString *)description {
         return [NSString stringWithFormat:@"name:%@,age=%li", _name, _age];
     }
    
     - (void)setAge:(NSInteger)age {
         _age = age;
     }
    
     @end

    main.m

     Person *p = [[Person alloc] init];
     //  p->_name = @"Zane";   不可訪问
    
     //1.使用KVC给private的属性设置值
     [p setValue:@"Zane" forKey:@"name"];
    
     //2.通过KVC获取到属性值
     NSString *name = [p valueForKey:@"_name"];
     NSLog(@"%@", name);
    
     [p setValue:@21 forKey:@"age"];
     NSLog(@"%@", p);

    output:

    2015-07-09 17:29:43.477 exercise_KVC[579:24344] Zane
    2015-07-09 17:29:43.478 exercise_KVC[579:24344] name:Zane,age=21

    1、键值编码(key-value coding):将表示对象包括的信息的字符串作为键值使用。来间接訪问该信息的方式。

    基本上,仅仅要存在訪问器方法、声明属性或实例变量,就能够将其名字作为字符串訪问

    (即使这个变量时@private私有的,也能訪问)


    2、设置属性值:

     - (void)setValue:(id)value forKey:(NSString *)key; //已进行内存管理
     [p setValue:@"Zane" forKey:@"name"];

    a、假设此处name写错了。写成nama。nam1e等等。编译器不会报错,但会导致执行崩溃
    b、value为id类型,因此假设是基本数据类型须要进行包装

    获取属性值

     - (id)valueForKey:(NSString *)key;
     NSString *name = [p valueForKey:@"_name"];

    假设人还拥有一条狗,以@class的方式加在Person.h中。狗有dogName属性,那么能够指定路径设置

    [p setValue:@"wangwang" forKeyPath:@"dog._dogname"];
    NSLog(@"%@",[p valueForKeyPath:@"dog._dogname"])
    - (id)valueForKeyPath:(NSString *)keyPath;
    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

    3、缺点
    (1)破坏了面向对象的封装性
    (2)编译器不会对设置的keyValue进行错误检查。
    (3)须要先对字符串进行解析,执行效率低于set和get方法


    4、其它说明
    (1)使用KVC设置属性。优先去当前类中查找是否有对应的set方法,假设有使用set方法设置,若无则找到属性设置
    要调用仅仅能写age不能写_age
    比如样例中的

    [p setValue:@21 forKey:@"age"];
    [p setValue:@21 forKey:@"_age"];

    能够在age的set方法实现处设置断点。会发现,假设写_age则不调用set方法

    (2)一对多的关系
    一般先打包成NSArray,再通过setValue方法,作为value赋值。


    訪问的时候通过路径訪问valueForKeyPath訪问

    (3)数值计算
    在上述样例中为Person添加book成员变量;
    而且Dog.h拥有成员变量dogage

     @interface Dog : NSObject
     {
         int _dogage;
     }
     - (instancetype)initWithAge:(int)age;   //并实现
     @end

    main.m

     Dog* dog1 = [[Dog alloc] initWithAge:20];
     Dog* dog2 = [[Dog alloc] initWithAge:30];
     Dog* dog3 = [[Dog alloc] initWithAge:10];
    
     NSArray *array = [NSArray arrayWithObjects:dog1,dog2,dog3, nil];
     [p setValue:array forKey:@"dog"];       //前面已定义
    
     NSLog(@"%@",[p valueForKeyPath:@"dog.@count"]);         //dog数量
     NSLog(@"%@",[p valueForKeyPath:@"dog.@sum._dogage"]);   //全部dogage总和
     NSLog(@"%@",[p valueForKeyPath:@"dog.@avg._dogage"]);   //平均值
     NSLog(@"%@",[p valueForKeyPath:@"dog.@min._dogage"]);   //最小值
     NSLog(@"%@",[p valueForKeyPath:@"dog.@max._dogage"]);   //最大值
    

    output:

    2015-07-09 17:29:43.479 exercise_KVC[579:24344] 3
    2015-07-09 17:29:43.479 exercise_KVC[579:24344] 60
    2015-07-09 17:29:43.480 exercise_KVC[579:24344] 20
    2015-07-09 17:29:43.480 exercise_KVC[579:24344] 10
    2015-07-09 17:29:43.480 exercise_KVC[579:24344] 30
  • 相关阅读:
    hadoop配置支持LZO压缩格式并支持分片
    CSS 图片:如何使用 CSS 来布局图片
    CSS3 用户界面:用户界面特性来调整元素尺寸,框尺寸和外边框
    CSS3 多列:如何将文本内容设计成像报纸一样的多列布局?
    mac Pycharm:如何使用anaconda安装jieba
    pycharm如何安装jieba词频统计器?
    CSS3 动画:使元素从一种样式逐渐变化为另一种样式的效果
    CSS3 过渡:用鼠标移过逐渐改变它原有样式
    CSS3 3D 转换:使用 3D 转换来对元素进行格式化
    CSS3 2D 转换:对元素进行移动、缩放、转动、拉长或拉伸
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7267845.html
Copyright © 2011-2022 走看看