iOS修改声明为readonly的属性值
本文讨论的是,对于类中声明为 readonly 的属性值,我们就不可以修改其值了么?如何可以,那么如何修改呢? 为了便于说明,定义一个 ACLStudent 的类: ACLStudent.h @interface ACLStudent : NSObject @property (nonatomic, assign, readonly) NSInteger studentId;
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName; - (instancetype)initWithStudentId:(NSInteger)studentId firstName:(NSString *)firstName lastName:(NSString *)lastName; @end -------------------------- ACLStudent.m @implementation ACLStudent - (instancetype)initWithStudentId:(NSInteger)studentId firstName:(NSString *)firstName lastName:(NSString *)lastName {
self = [super init];
if (self) {
_studentId = studentId;
_firstName = [firstName copy];
_lastName = [lastName copy];
} return self;
} @end 接下来定义一个 ACLStudent 类的对象: ACLStudent *student = [[ACLStudent alloc] initWithStudentId:1 firstName:@"Carya" lastName:@"Liu"];
NSLog(@"student firstName: %@", student.firstName); 现在我们考虑的就是如何修改 student 对象的 firstName 属性值为 @"Qiu" 。 如果直接调用 firstName 的 setter 方法, student.firstName = @"Qiu" , 那么就直接报错,提示不能够给声明为 readonly 的属性赋值。那么使用 KVC 呢? [student setValue:@"Qiu" forKey:NSStringFromSelector(@selector(firstName))];
NSLog(@"student firstName after changed: %@", student.firstName); 运行,发现属性值被成功修改。哈哈,那么现在来看看 KVC 为什么能够修改该属性值呢?看看文档 Accessor Search Implementation Details 。 当使用 setValue:forKey: 来设置对象的属性时,会以下面的优先顺序来寻找对应的 key : 消息接收对象会查找是否存在满足 set<Key>: 格式的存取方法。
如果不存在满足条件的存取方法,且消息接收对象的类方法 + (BOOL)accessInstanceVariablesDirectly 返回 YES,那么该对象会以 _<key> , _is<Key> , <key> , is<Key> 的顺序查找是否存在对应的key。
如果存在对应的存取方法或者找到对应的实例变量,那么就会改变该 key 所对应的值 value。必要的话,value 所对应的值会从对象中解析出来,如 Representing Non-Object Values 所描述的那样。
如果没有找到对应的存取方法或者实例变量,那么该消息对象的 setValue:forUndefinedKey: 将会调用。 对于上述第2点说明一下,如果我们不想让 setValue:forKey: 方法改变对象的属性值,那么重写其类方法 + (BOOL)accessInstanceVariablesDirectly 返回 NO (该方法默认返回 YES,即在不存在满足条件的存取方法时,允许直接访问属性对应的实例变量);在搜索实例变量时,会首先检查带下划线的实例变量,然后检查不带下划线的实例变量。 对于上述第3点举例说明,如果修改 student 对象的属性 NSInteger studentId , 注意其是 NSInteger 类型,我们在调用 setValue:forKey: 方法时可以像这样 [student setValue:@(20) forKey:NSStringFromSelector(@selector(studentId))]; 传入一个 NSNumber 对象也可以,Objective-C 会处理好一切。 对于上面的示例,使用 setValue:forKey: 实际修改的是 student 实例中 _firstName 实例变量的值。不要忘记,我们在声明一个 firstName 的属性时,编译器会为我们自动合成一个 _firstName 的实例变量。 总结: 当我们声明一个 readonly 的属性,外部可能会通过 KVC 修改该属性值。
为了避免 KVC 修改属性值,须将定义属性所在类的类方法 + (BOOL)accessInstanceVariablesDirectly 重写,使其返回 NO.
iOS修改声明为readonly的属性值的更多相关文章
- jquery attr()方法 添加,修改,获取对象的属性值。
jquery attr()方法 添加,修改,获取对象的属性值. jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到 ...
- 【iOS】Quartz2D练习-动态改变属性值
一.通过slider控制圆的缩放 1.实现过程 新建一个项目,新建一个继承自UIview的类,并和storyboard中自定义的view进行关联.代码示例:SLViewController.m文件 # ...
- JQuery 操作对象的属性值
通过JQuery去操作前台对象(div,span...)的属性是很常见的事情,本文就简单的介绍几种操作情形. 1):通过属性值去获取对象 2):用JQuery去修改对象的属性值 3):获取并修改对象的 ...
- CSS学习(7)继承、属性值的计算过程
子元素会继承父元素的某些css属性 通常跟字体相关的属性都能被继承,具体的可以在mdn里查询是否是可继承属性 属性值的计算过程(渲染过程) 按照页面文档的树形目录结构进行依次渲染 前提条件:渲染的元素 ...
- 关于Javascript中通过实例对象修改原型对象属性值的问题
Javascript中的数据值有两大类:基本类型的数据值和引用类型的数据值. 基本类型的数据值有5种:null.undefined.number.boolean和string. 引用类型的数据值往大的 ...
- tween.js是一款可生成平滑动画效果的js动画库。tween.js允许你以平滑的方式修改元素的属性值。它可以通过设置生成各种类似CSS3的动画效果。
简要教程 tween.js是一款可生成平滑动画效果的js动画库.相关的动画库插件还有:snabbt.js 强大的jQuery动画库插件和Tweene-超级强大的jQuery动画代理插件. tween. ...
- dom4j修改,获取,增加xml中某个元素的属性值
XML文件: <?xml version="1.0" encoding="UTF-8"?> <vrvscript> <item I ...
- 使用SetWindowPos API函数移动窗口后,还需修改Delphi的属性值,以备下次使用,否则就会出问题(不是API不起作用,而是使用了错误的坐标值)
单独改变坐标的代码如下,可不断左移: procedure TForm1.Button1Click(Sender: TObject); begin SetWindowPos(panel1.Handle, ...
- iOS 将对象的属性和属性值拆分成key、value,通过字符串key来获取该属性的值
这篇博客光看标题或许就会产生疑问,某个对象,只要它存在某个属性,且值不是空的,不就能直接用点方法获取吗,为什么要拆分成key和value多此一举呢?下面,我用一个例子告诉大家,既然这方法是存在的,那就 ...
随机推荐
- Oracle数据库中的违规策略规则的修正
如笔者计算机上违规的策略与规则: 为了安全,可如下方式对齐进行修正:
- java开发者最常去的20个英文网站
java开发者最常去的20个英文网站: 1.[http://www.javaalmanac.com] Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧的用法及示例代码, 这是一个不错的 ...
- 《Java数据结构与算法》笔记-CH2有序数组
/** * 上个例子是无序数组,并且没有考虑重复元素的情况. * 下面来设计一个有序数组,我们设定不允许重复,这样提高查找的速度,但是降低了插入操作的速度. * 1.线性查找 * 2.二分查找 * 有 ...
- mysql的登录密码带特殊符号登录不进去的问题
eg : mysqldump -u root -p)P:9 ${dbname} > $dataPath$filename 当我将数据库的数据每天进行自动导出时,需要带上密码,但 ) 是一个特殊符 ...
- [转载] I wish you enough
几天前,我在机场无意中听到一对父女告别时最后一刻的对白.广播员已经通知大家准备登机了.他们站在安检口旁边紧紧拥抱,父亲对女儿说:“我爱你,希望你一切都充足!” 女儿回答:“爸爸,我是那么满足我们在一起 ...
- linux下开发c++第二弹--helloworld与makefile
一:hello world sudo vim hello.cpp 输入 g++ -o hello hello.cpp 获得hello 输入 ./hello 运行,显示结果hello world! ...
- ocp 1Z0-043 1-60题解析
1.You observe that a database performance has degraded overa period of time. While investigating the ...
- POJ 3259 Wormholes(最短路,判断有没有负环回路)
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24249 Accepted: 8652 Descri ...
- [iOS基础控件 - 6.11.5] 沙盒 & 数据存储
A.沙盒 每个APP都有一个沙盒,是独立存在的 1.Xcode5和Xcode6的模拟器文件目录 a.模拟器路径改版 (1)Xcode5中模拟器路径为:/Users/用户名/Library/Appl ...
- python中列表,元组,字符串如何互相转换
python中有三个内建函数:列表,元组和字符串,他们之间的互相转换使用三个函数,str(),tuple()和list(),具体示例如下所示: >>> s = "xxxxx ...