修改readonly修饰属性的值!

本文深入探讨了Objective-C中readonly属性的使用方法及其限制。通过一个具体的Animal类实例,展示了如何正确应用readonly属性,以及如何防止通过KVC方式修改这些属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

readonly

情景

当我们的对象的某些个属性不需要对外提供set方法修改赋值时,那么我们在定义属性时会给属性添加readonly。

问题

1.那么是不是只要添加readonly后就不能改属性值了呢?

下面先定义一个Animal类

.h文件
#import <Foundation/Foundation.h>

@interface Animal : NSObject

@property(nonatomic,readonly,copy)NSString * name;
-(instancetype)initWithName:(NSString *)name;

@end
-----------------------------------------------------
.m文件
#import "Animal.h"

@implementation Animal

-(instancetype)initWithName:(NSString *)name{

    if (self = [super init]) {
        _name = [name copy];
    }
    return self;
}

调用

Animal * a = [[Animal alloc]initWithName:@"lucy"];

当使用a.name 进行赋值时,系统会直接提示”Assignment to readonly property”

2.那使用kvc呢?

[a setValue:@"tom" forKey:@"name"];

NSLog(@"%@",a.name);

运行后发现可以修改name的值.

3.如何防止kvc修改readonly属性值呢?

重写自定义类的“accessInstanceVariablesDirectly”方法,让其返回值为NO。

+(BOOL)accessInstanceVariablesDirectly{
    return NO;
}

当尝试使用kvo改变readonly属性值时会抛出如下异常:

reason: '[<Animal 0x600000019e40> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'

原理:
当使用setValue:forKey:来设置对象属性的值时系统会按一下顺序来查找对应的key:

 1.查找是否存在set<key>:这样格式的方法;

 2.如果上面方法未找到,则接受消息对象的类方法“accessInstanceVariablesDirectly”会返回YES(默认返回YES),再按下面顺序继续查找;

 3._<key> , _is<Key> , <key> , is<Key> 的顺序查找是否存在对应的key,如果找到将改变key所对应的值。

 4.最后还是没有找到对应的存取方法或者实例变量,那么将走进 setValue:forUndefinedKey: 抛出如下异常:

reason: '[<Animal 0x60400001ec70> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key namekk.'

关键点便在上面的第2步accessInstanceVariablesDirectly方法的调用,系统默认是返回YES,我们将该方法重写后,让其返回NO,这样就直接走进setValue:forUndefinedKey:方法,并抛出异常,进行提示!

(实际开发中苹果肯定是不建议我们这样玩readonly,既然使用了readonly,干嘛又要反复修改他的值,真要修改,直接去掉readonly不就好了!^_^ 这里仅做技术探讨,如有不足请指出,分享出来仅供参考!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值