探索iOS中的KVC

目录

前言

1.iOS中的KVC(键值编码)

1. 什么是KVC?

2. 使用KVC

1.设置属性值

2.获取属性值

3. KVC的高级用法

1.访问私有属性

2.访问集合属性

4. KVC的安全性

5. KVC原理

1. 查找顺序

2. 设置值

6.参考文章


前言

        这篇文章主要是介绍KVC的用法。

1.iOS中的KVC(键值编码)

        在iOS开发中,KVC(Key-Value Coding,键值编码)是一种强大的机制,使得我们能够通过字符串键来访问对象的属性。KVC在许多iOS框架和技术中扮演着关键角色,包括Core Data、Cocoa Bindings以及KVO(Key-Value Observing,键值观察)。

1. 什么是KVC?

        KVC是一种间接访问对象属性的方法。通常,我们通过属性的getter和setter方法来访问或修改对象的属性。但使用KVC,我们可以通过字符串键来访问这些属性,这使得代码更加灵活和动态。

2. 使用KVC

        KVC主要通过setValue:forKey和valueForKey:方法来实现。

1.设置属性值

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;

@end

@implementation Person
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        
        // 使用KVC设置属性值
        [person setValue:@"John" forKey:@"name"];
        [person setValue:@30 forKey:@"age"];
        
        NSLog(@"Name: %@", person.name);
        NSLog(@"Age: %ld", (long)person.age);
    }
    return 0;
}

2.获取属性值

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        [person setValue:@"John" forKey:@"name"];
        [person setValue:@30 forKey:@"age"];
        
        // 使用KVC获取属性值
        NSString *name = [person valueForKey:@"name"];
        NSNumber *age = [person valueForKey:@"age"];
        
        NSLog(@"Name: %@", name);
        NSLog(@"Age: %@", age);
    }
    return 0;
}

3. KVC的高级用法

1.访问私有属性

        KVC不仅可以访问公共属性,还可以访问私有属性。尽管这是KVC的一个强大功能,但在实际开发中要谨慎使用。

@interface Person ()

@property (nonatomic, strong) NSString *secret;

@end

@implementation Person
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        
        // 使用KVC访问私有属性
        [person setValue:@"This is a secret" forKey:@"secret"];
        NSString *secret = [person valueForKey:@"secret"];
        
        NSLog(@"Secret: %@", secret);
    }
    return 0;
}

2.访问集合属性

        KVC还提供了一些便捷方法来访问集合类型的属性,如数组和字典。

@interface Group : NSObject

@property (nonatomic, strong) NSArray<Person *> *members;

@end

@implementation Group
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person1 = [[Person alloc] init];
        [person1 setValue:@"Alice" forKey:@"name"];
        [person1 setValue:@25 forKey:@"age"];
        
        Person *person2 = [[Person alloc] init];
        [person2 setValue:@"Bob" forKey:@"name"];
        [person2 setValue:@28 forKey:@"age"];
        
        Group *group = [[Group alloc] init];
        group.members = @[person1, person2];
        
        // 使用KVC访问集合属性
        NSArray *names = [group valueForKeyPath:@"members.name"];
        NSLog(@"Names: %@", names);
    }
    return 0;
}

4. KVC的安全性

        使用KVC时需要注意一些安全性问题,例如:
        - 如果指定的键不存在,KVC会抛出一个异常。
        - 访问或修改私有属性可能违反封装性原则。

        因此,使用KVC时要确保键的正确性,并且要对可能出现的异常进行适当的处理。

5. KVC原理

        KVC 的实现主要依赖于以下几个方面:

1. 查找顺序

             当通过 `valueForKey:` 获取值时,KVC 按以下顺序查找属性:

  1. Getter 方法:首先查找与键对应的 getter 方法。例如,对于键 `name`,查找 `getName`、`name` 或 `isName` 方法。
  2.  实例变量:如果没有找到合适的 getter 方法,则查找以键命名的实例变量 `_name` 或 `name`
  3.   -accessInstanceVariablesDirectly:如果前两个查找都失败,KVC 会调用 `accessInstanceVariablesDirectly` 方法,该方法返回 YES 表示可以直接访问实例变量。

2. 设置值

        当通过setValue:forKey:设置值时,KVC 按以下顺序查找属性:

  1. Setter 方法:首先查找与键对应的 setter 方法。例如,对于键 name,查找 setName: 方法。
  2. 实例变:如果没有找到合适的 setter 方法,则查找以键命名的实例变量_name或 name
  3. setValue:forUndefinedKey:如果前两个查找都失败,KVC 会调用 `setValue:forUndefinedKey:` 方法,该方法通常会抛出一个异常。

#### KVC 的查找规则示例

@interface Person : NSObject {
    NSString *_name;
}
@property (nonatomic, strong) NSString *name;
@end

@implementation Person
@end

当调用 `[person valueForKey:@"name"]` 时,KVC 的查找顺序如下:

1. 查找 `- (NSString *)name` 方法。
2. 查找 `- (NSString *)getName` 方法。
3. 查找 `- (NSString *)isName` 方法。
4. 查找实例变量 `_name` 和 `name`。
5. 调用 `accessInstanceVariablesDirectly` 方法,返回 YES,直接访问 `_name`。

当调用 [person setValue:@"John" forKey:@"name"] 时,KVC 的查找顺序如下:

1. 查找 - (void)setName:(NSString *)name 方法。
2. 查找实例变量 `_name` 和 `name`。
3. 调用 `setValue:forUndefinedKey:` 方法。

6.参考文章

1.Key-Value Coding Programming Guide: About Key-Value Coding

  • 31
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
引用提到了在严格模式下使用map的function声明时,this指向undefined。这可能导致一些问题。解决方法是将map里面的function声明修改为箭头函数,因为箭头函数没有自己的this,它会继承父级作用域的this。这样就可以避免this指向undefined的问题。 引用提到了setValue:ForKey:是KVC的主要方法,而setObject:ForKey:是NSMutableDictionary特有的方法。两者之间有一些区别。如果你是在使用NSMutableDictionary,应该使用setObject:ForKey:来设置对象的值。而如果你是在使用KVC,应该使用setValue:ForKey:来设置对象的值。 引用提到了在GetNav方法使用map遍历数组,并为每个元素动态生成一列数据,并为每一列数据添加了onClick事件。但在运行过程报错说updateRoute为undefined。根据错误信息来看,可能是updateRoute这个方法未定义。需要检查代码是否有定义这个方法,并且确保被正确引用。 综上所述,问题的解决方法包括: 1. 将map里面的function声明修改为箭头函数,以解决严格模式下this指向undefined的问题。 2. 根据具体情况选择使用setValue:ForKey:或setObject:ForKey:方法来设置对象的值。 3. 检查代码是否正确定义了updateRoute方法,并确保正确引用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [TypeError:Cannot read properties of undefined(reading XXX)](https://blog.csdn.net/qq_57558631/article/details/124961465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [iOSsetValue和setObject的区别详解](https://download.csdn.net/download/weixin_38701407/12786722)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫柱子哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值