Objective-C语法之KVC使用

2023-10-28

除了一般的赋值和取值的方法,我们还可以用Key-Value-Coding(KVC)键值编码来访问你要存取的类的属性。

下图来自苹果官网:

 

如何使用KVC存取对象属性呢?看个示例

1、使用KVC

定义一个Student类,继承于NSObject。

.h文件

#import <Foundation/Foundation.h>

@interface Student : NSObject
{
    NSString *name;
}
@end

.m文件

#import "Student.h"

@implementation Student

@end

.m文件也没有实现。name属性没有加property,原来的访问方法就访问不了name属性了。怎么办呢?用kvc就可以了

#import "Student.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *student = [[[Student alloc]init ]autorelease];
        [student setValue:@"张三" forKey:@"name"];
        NSString *name = [student valueForKey:@"name"];
        NSLog(@"学生姓名:%@",name);
    }
    return 0;
}

打印结果:

2012-07-20 15:04:09.920 objectiveC[1977:403] 学生姓名:张三

张三 这个值存进去了,通过valueForKey取出来了。

如果存的时候key和类属性的名称不一致会怎么样呢?

代码改成 

        [student setValue:@"张三" forKey:@"name1"];

运行,程序崩溃 ,打印:

2012-07-20 15:09:40.432 objectiveC[2069:403] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Student 0x106f14270> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name1.'

提示没有这个name1 这个key。

2、键路径访问属性

如果访问这个类里中的属性中的属性呢?那就用到了键路径 

关键字:键路径取值valueForKeyPath 键路径存值:forKeyPath

新建一个类Course,课程类,课程类有课程名称这个属性

.h文件

#import <Foundation/Foundation.h>

@interface Course : NSObject
{
    NSString *CourseName;
}
@end

.m文件

#import "Course.h"

@implementation Course

@end

在Student中添加Course属性 ,student.h文件中代码如下:

#import <Foundation/Foundation.h>
@class Course;
@interface Student : NSObject
{
    NSString *name;
    Course *course;
}
@end

实现还是什么都没有,这里就不贴代码了

在main方法中,我们实验通过键路径访问Course中CourseName的属性

#import "Student.h"
#import "Course.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *student = [[[Student alloc]init ]autorelease];
        [student setValue:@"张三" forKey:@"name"];
        NSString *name = [student valueForKey:@"name"];
        NSLog(@"学生姓名:%@",name);
        
        Course *course = [[[Course alloc]init] autorelease];
        [course setValue:@"语文课" forKey:@"CourseName"];
        [student setValue:course forKey:@"course"];
        NSString *courseName = [student valueForKeyPath:@"course.CourseName"];
        NSLog(@"课程名称:%@", courseName);
        
        //也可以这样存值
        [student setValue:@"数学课" forKeyPath:@"course.CourseName"];
        courseName = [student valueForKeyPath:@"course.CourseName"];
        NSLog(@"课程名称:%@", courseName);
        
    }
    return 0;
}

运行打印结果:

2012-07-20 15:33:51.902 objectiveC[2415:403] 学生姓名:张三

2012-07-20 15:33:51.904 objectiveC[2415:403] 课程名称:语文课

2012-07-20 15:33:51.904 objectiveC[2415:403] 课程名称:数学课

3、自动封装基本数据类型

我们在Student类中添加分数属性 NSInteger point;

.h文件

#import <Foundation/Foundation.h>
@class Course;
@interface Student : NSObject
{
    NSString *name;
    Course *course;
    NSInteger point;
}
@end

.m文件不改变

#import "Student.h"
#import "Course.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *student = [[[Student alloc]init ]autorelease];
        [student setValue:@"张三" forKey:@"name"];
        NSString *name = [student valueForKey:@"name"];
        NSLog(@"学生姓名:%@",name);
        
        Course *course = [[[Course alloc]init] autorelease];
        [course setValue:@"语文课" forKey:@"CourseName"];
        [student setValue:course forKey:@"course"];
        NSString *courseName = [student valueForKeyPath:@"course.CourseName"];
        NSLog(@"课程名称:%@", courseName);
        
        //也可以这样存值
        [student setValue:@"数学课" forKeyPath:@"course.CourseName"];
        courseName = [student valueForKeyPath:@"course.CourseName"];
        NSLog(@"课程名称:%@", courseName);
        
        [student setValue:@"88" forKeyPath:@"point"];
        NSString *point = [student valueForKey:@"point"];
        NSLog(@"分数:%@", point);
        
    }
    return 0;
}

打印结果:

2012-07-20 15:43:19.593 objectiveC[2533:403] 学生姓名:张三

2012-07-20 15:43:19.596 objectiveC[2533:403] 课程名称:语文课

2012-07-20 15:43:19.596 objectiveC[2533:403] 课程名称:数学课

2012-07-20 15:43:19.598 objectiveC[2533:403] 分数:88

我们用NSString*类型设置的属性值@"88",而我们的属性是NSInteger类型的,存取都没有问题。

4、操作集合

在Student类中加入数组NSArray,用来表示其他的学生。这样我们可以添加多个其他的学生,再用集合操作计算学生的分数,最高分,最低分,平均分等

#import <Foundation/Foundation.h>
@class Course;
@interface Student : NSObject
{
    NSString *name;
    Course *course;
    NSInteger point;
    NSArray *otherStudent;
}
@end

.m文件实现不变。

在main函数中添加三个学生,添加到数组中,然后求平均分,最高,最低分,学生数量

#import "Student.h"
#import "Course.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *student = [[[Student alloc]init ]autorelease];
        [student setValue:@"张三" forKey:@"name"];
        NSString *name = [student valueForKey:@"name"];
        NSLog(@"学生姓名:%@",name);
        
        [student setValue:@"88" forKey:@"point"];
        NSString *point = [student valueForKey:@"point"];
        NSLog(@"分数:%@", point);
        
        Student *student1 = [[[Student alloc]init]autorelease];
        Student *student2 = [[[Student alloc]init]autorelease];
        Student *student3 = [[[Student alloc]init]autorelease];
        [student1 setValue:@"65" forKey:@"point"];
        [student2 setValue:@"77" forKey:@"point"];
        [student3 setValue:@"99" forKey:@"point"];
        NSArray *array = [NSArray arrayWithObjects:student1,student2,student3,nil];
        [student setValue:array forKey:@"otherStudent"];
        NSLog(@"其他学生的成绩%@", [student valueForKeyPath:@"otherStudent.point"]);
        NSLog(@"共%@个学生", [student valueForKeyPath:@"otherStudent.@count"]);
        NSLog(@"最高成绩:%@", [student valueForKeyPath:@"otherStudent.@max.point"]);
        NSLog(@"最低成绩:%@", [student valueForKeyPath:@"otherStudent.@min.point"]);
        NSLog(@"平均成绩:%@", [student valueForKeyPath:@"otherStudent.@avg.point"]);
    }
    return 0;
}

运行打印结果

2012-07-20 16:09:17.101 objectiveC[2857:403] 学生姓名:张三

2012-07-20 16:09:17.104 objectiveC[2857:403] 分数:88

2012-07-20 16:09:17.105 objectiveC[2857:403] 其他学生的成绩(

    65,

    77,

    99

)

2012-07-20 16:09:17.106 objectiveC[2857:403] 3个学生

2012-07-20 16:09:17.106 objectiveC[2857:403] 最高成绩:99

2012-07-20 16:09:17.107 objectiveC[2857:403] 最低成绩:65

2012-07-20 16:09:17.108 objectiveC[2857:403] 平均成绩:80.333333333333333333333333333333333333

还可以求总和  @sum。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Objective-C语法之KVC使用 的相关文章

  • iOS UITableViewCell需要按两次才能调用didSelectRowAtIndexPath

    我有一个 UITableView 有时需要您触摸它两次才能选择一个单元格 更多细节 仅当表格一直向上或一直向下滚动后才需要两次触摸 只需第二次触摸即可呼叫didSelectRowAtIndexPath 当表格以自然的 向上滚动位置 打开时
  • 如何改进 iOS 中的 TWTweetComposeViewController 代码?

    我已经实现了以下代码来进行 Twitter 共享 在我的代码中 我尝试测试 iOS 5 如果这不起作用 我会回到使用 ShareKit 的 Twitter 代码进行共享的旧方式 我向同事展示了代码 他建议我的代码可能有缺陷 我需要做两件事
  • iPhone - 创建图像网格列表

    我正在开发一个应用程序 它从网站获取图像并使用网格视图向用户显示 例如Apple的照片应用程序 当您点击图像时 我会推送一个显示图像信息和其他内容的视图控制器 实现这个的更好方法是什么 我想到了自定义 UITableViewCell 我见过
  • CNContact 添加新的联系人问题

    我在通过以下方式添加联系人时遇到问题联系框架 我使用的是装有 iOS 12 1 2 的 iPhone 5s 设备 我添加联系人的代码如下 let saveRequest CNSaveRequest saveRequest add self
  • 检测您何时进入/退出 Xamarin.iOS 中的主线程

    Xamarin MonoTouch 有没有办法检测主线程中是否正在调用代码 我正在寻找类似于Java的东西EventQueue isEventDispatchThread 我发现 Swing 编程很方便assert时不时 或有时assert
  • iOS UITableViewCell 配件在左侧?

    对于我的应用程序 我想要一些可以同时具有复选标记和详细信息披露按钮的单元格 也就是说 我希望它们看起来与 iOS 设置中的 Wi Fi 网络选择一模一样 左侧的复选标记 中间的内容 右侧的详细信息披露按钮 有没有正确的方法来做到这一点 或者
  • 自动布局:Y 位置为两个值中的最大值

    我有一个按钮 play Button 和两个 UIView myView 1 和 myView 2 它们的位置在执行过程中可能会发生变化 我希望 playButton 的顶部比 UIView 1 的底部或 UIView 2 的底部低 10
  • Swift 3 '[UIApplicationLaunchOptionsKey:任意]?'无法转换为 '[String : NSString]'

    我有一个 TVOS 应用程序已从 Swift 2 转换为 Swift 3 但出现以下错误 我不确定如何让它安静下来 UIApplicationLaunchOptionsKey 任意 无法转换为 String NSString 它出现在这段代
  • 适用于 iOS 的 Google Cast SDK 2.3.0 不支持 64 位

    似乎是适用于 iOS 的 Google Cast SDK 2 3 0 版本 https developers google com cast downloads GoogleCastFramework 2 3 0 Release zip停止
  • iOS App布局错误,调用状态栏

    在主动通话和应用程序布局期间面临状态栏问题 我正在使用自动布局 当我运行应用程序 然后开始通话时 一切正常 UI 会随着状态栏的更改而正确缩放 但是 如果我首先开始通话 然后运行应用程序 应用程序屏幕会移动到底部 20pt 就像它们对新状态
  • 使用 UIImagePickerController 的应用程序在拍照后选择“使用照片”时冻结

    我现在正在开发一个简单的照片和视频捕获应用程序 该应用程序成功地允许用户按下按钮即可拍摄照片或视频 但是 一旦您完成拍摄照片或视频 它就会提供 2 个选项 重新拍摄 和 使用照片 或 使用视频 具体取决于您使用的选项 如果用户点击 重新拍摄
  • WebGL iOS 渲染为浮点纹理

    我正在尝试在 iOS Safari 上的 WebGL 中渲染浮点纹理 而不是在本机应用程序中 我已经设法让 iOS 读取手动 例如从 JavaScript 创建的浮点纹理 但是当我创建浮点类型的帧缓冲区并使用 GPU 渲染到其中时 它不起作
  • 从 Core Data、iOS 获取最后插入的项目

    有没有办法获取核心数据数据库中最后插入的项目 这将返回最后插入的对象 setFetchLimit 1 和 setFetchOffset 所有条目数 1
  • 为了支持 iPhone 5 的更长屏幕,需要检查什么? [复制]

    这个问题在这里已经有答案了 可能的重复 iPhone 5屏幕尺寸如何处理 https stackoverflow com questions 12396545 how to deal with iphone 5 screen size iP
  • 在 Swift 中检查一个数组是否包含另一个数组的所有元素

    我想为数组编写一个扩展来检查一个数组是否包含另一个数组的所有元素 在我的用例中它是字符串对象 但我一直得到 Cannot convert value of type T Generator Element to expected argum
  • Cognito/IAM 策略和 S3 获取对象

    我正在尝试将 S3 和 Cognito 集成到我的 iOS 应用程序中 但到目前为止尚未成功 我相信该错误与我针对 Auth 和 Unauth 用户的 IAM 策略有关 所以这是我的政策 Version 2012 10 17 Stateme
  • 应用未能及时恢复

    我在一个非常具体的场景中遇到 未能及时恢复 崩溃 我认为与看门狗相关 仅在从后台恢复时 并且仅在进入后台后在很短的时间内执行此操作 a最多几秒钟 这似乎是相关的崩溃日志 Incident Identifier E30F2238 5B15 4
  • 如何自动为 Swift 类创建初始化程序?

    UPDATE 使用结构而不是类 struct 在很多方面都更好 它有自己的初始化器 这是我的模型课 是否有可能创建init自动方法 每次我都必须将所有变量一一初始化 这会花费很多时间 class Profile var id String
  • iOS 发送 iMessage 尽可能简单

    我希望能够以编程方式发送 iMessage 除了调用一个将文本发送到带有消息的号码的函数之外 无需执行任何其他操作 这两个消息都是文本框 我真的很感激一些示例代码 因为我在网上搜索过 但我发现没有任何帮助 这不适用于商业应用程序 仅适用于我
  • 通用类不会将委托调用转发给具体子类

    鉴于以下情况 protocol EntityType var displayString String get extension String EntityType var displayString String return self

随机推荐

  • #if defined() 含义

    文章出处 http www blogjava net tinysun archive 2010 07 27 327215 html 看到内核代码中有很多地方都使用了 if defined 可是却找不到这个东东的定义 主要是define 它和
  • 【C语言】指针进阶(二)

    个人主页 阿然成长日记 点击可跳转 个人专栏 数据结构与算法 C语言进阶 不能则学 不知则问 耻于问人 决无长进 目录 四 数组名详解 1 数组名的理解 2 案例分析1 案例分析2 五 函数指针 1 其声明形式如下所示 2 函数指针的初始化
  • 起亚汽车RFID定位管理系统提升了物流运输效率

    1 应用背景 英国物流提供商Paragon Automotive部署RFID定位管理解决方案跟踪伊明赫姆港口附近的起亚汽车 这些汽车都在这个港口喷漆 存储并运送到其他零售地点 RFID定位管理系统使用了Paragon自己的管理软件 移动及固
  • python怎么获取免费代理IP

    什么是免费代理IP 免费代理IP是指可以免费使用的代理服务器的IP地址 代理服务器充当客户端和目标服务器之间的中间人 通过转发请求和响应来实现网络数据的传输 使用代理IP可以隐藏真实的客户端IP地址 实现匿名访问网络资源 免费代理IP通常由
  • 减轻剪辑工作必备——Python实现让视频自动打码,再也不怕出现少儿不宜的画面了

    我们在观看视频的时候 有时候会出现一些奇怪的马赛克 影响我们的观影体验 那么这些马赛克是如何精确的加上去的呢 有什么python相关报错解答自己不会的 或者源码资料 模块安装 女装大佬精通技巧 都可以来这里 https jq qq com
  • ffmpeg多个流画面合并

    首先这个是两路视频流的合并 要实现将两个视频一左一右同时播放的效果 可以使用FFmpeg的hstack和vstack滤镜来实现 以下是一种常见的方法 ffmpeg i input1 mp4 i input2 mp4 filter compl
  • sed命令详解

    简介 sed是非交互式的编辑器 它不会修改文件 除非使用shell重定向来保存结果 默认情况下 所有的输出行都被打印到屏幕上 sed编辑器逐行处理文件 或输入 并将结果发送到屏幕 具体过程如下 首先sed把当前正在处理的行保存在一个临时缓存
  • 技术人员如何形成差异化竞争力让自己活下去

    随着大的经济环境的影响 我看到很多人开始变得焦虑 技术人员也开始焦虑 其实我也会焦虑 从宏观角度来看 国内很多企业一直走不出国门 难以进一步做增长 导致需求减少 而互联网行业也整体进入稳定期 对新业务不再像以前那样不计成本 导致需要的人也大
  • 如何快速入门深度学习目标检测?

    学习目标 了解目标检测的任务 知道目标检测的常用数据集 知道目标检测算法的评价指标 掌握非极大值NMS算法的应用 了解常用的目标检测算法分类 1 目标检测 目标检测 Object Detection 的任务是找出图像中所有感兴趣的目标 并确
  • 打包jar到maven本地仓库

    有时候时间打包的sdk需要集成到其他工程里面 然后需要把sdk打包到工程的仓库里面 命令如下 mvn install install file Dfile jar所在的路径 DgroupId groupId名字 自己随便取 Dartifac
  • PID算法C语言模拟演示

    由于暂时没有硬件平台 网上找到一篇 用C语言实现PID控制代码 写的非常好 参照其文章 自己也动手实验了一下 下面通过几张 Execl 截屏说明下 Kp Ki Kd 三个参数不同取值时的输出效果 感谢CSDN博主 生活不易到处是坑 的原创文
  • 华为面试算法题

    华为面试算法题1 给定一个n 2的二维数组 表示有n个任务 一个信息是任务能够开始做的时间 另一个信息是任务的结束期限 后者一定大于前者 且数值上都是正数 你作为单线程的人 不能并行处理任务 但是每个任务都只需要一个单位时间完成 你需耍将所
  • vue3+vite+ts--watch和watchEffect监听使用

    目录 一 watch的使用方法 二 watchEffect的使用方法 三 watch和watchEffect的区别 一 watch的使用方法 watch 监听的数据 监听数据的函数 监听配置对象 是否立即执行 是否开启深度监听 watch
  • R语言课后习题

    R安装 1 输入命令 B 在浏览器中显示帮助文档 并学会使用帮助文档 A help solve B help start C help D data 2 函数 D 可在当前会话中执行一个脚本 A demo test B rm test C
  • el-table选中数据后echarts数据更新

    项目场景 在做后台管理系统中 数据分析模块必不可少 所以要用到echarts来实现此功能 例如 在el table中选中某条数据后echarts会更新数据 初始化的时候echarts数据是后端返回的默认数据 常规数据操作 提示 在这里记录一
  • JavaEE项目实战(OA系统)之十八_流程审批之一

    JavaEE项目实战 OA系统 之十八 流程审批之一 下面介绍OA系统的另一模块 流程审批 OA系统推崇的是无纸化办公 因此各项事务的流程审批是OA系统的一大类应用 下面 我们来设计流程审批的数据库 首先 我们来看一张图 所谓的 流程审批
  • Windows11 搭建WSL运行CentOS7(WSL+Pycharm环境搭建系列之一)

    Windows11 搭建WSL运行CentOS7 0 前言 1 启动 WSL 2 启动虚拟机平台功能 3 下载并安装Linux 内核更新包 4 将WSL2设置为默认版本 5 选择Linux发行版进行安装 6 如何判定WSL的发行版安装成功
  • SSM 高级面试题

    Spring 依赖注入方式有那些 参考答案 通过构造器注入 通过 setter 注入 通过 filed 注入 Spring Boot 特点有哪些 参考答案 Spring Boot 的特点 1 快速开发 Spring 应用的框架 2 内嵌 T
  • 只要九分钟,用神经网络构建人脸比对模型

    多年以后 面对CSDN专栏 我仍会想起大二肄业后首次面对投资人的那个遥远下午 一位都不知道 Python 是什么的投资人对我说 神经网络这个事 博士都不一定够 得是教授才能做 那时的亚马逊中国只有一本关于书里的一章是关于神经网络 内容还是批
  • Objective-C语法之KVC使用

    除了一般的赋值和取值的方法 我们还可以用Key Value Coding KVC 键值编码来访问你要存取的类的属性 下图来自苹果官网 如何使用KVC存取对象属性呢 看个示例 1 使用KVC 定义一个Student类 继承于NSObject