若一个类有实例变量 NSString *_foo ,调用setValue:forKey:时,可以以foo还是 _foo 作为key?

KVC在Objective-C中用于访问和修改对象属性,即使没有公开的setter方法。当setValue:forKey:被调用时,它会按顺序尝试通过setter、成员变量、下划线开头的变量以及驼峰命名的变量进行赋值。如果不存在匹配的key,会执行valueForUndefinedKey:方法,默认抛出异常。测试显示,KVC优先尝试成员变量,并遵循特定的查找顺序。



*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ViewController 0x7fead440c430> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key _foo.'


答案:都可以

为什么?

无论是Swift还是Objective-C,KVC的定义都是对NSObject的扩展来实现的(Objective-c中有个显式的NSKeyValueCoding类别名,而Swift没有这个类别,也不需要)所以对于所有继承了NSObject在类型,都能使用KVC(一些纯Swift类和结构体是不支持KVC的),下面是KVC最为重要的四个方法:

- (nullable id)valueForKey:(NSString *)key;                          //直接通过Key来取值
- (void)setValue:(nullable id)value forKey:(NSString *)key;          //通过Key来设值
- (nullable id)valueForKeyPath:(NSString *)keyPath;                  //通过KeyPath来取值
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;  //通过KeyPath来设值

其他的一些方法:

+ (BOOL)accessInstanceVariablesDirectly;
//默认返回YES,表示如果没有找到Set方法的话,会按照_key,_iskey,key,iskey的顺序搜索成员,设置成NO就不这样搜索
- (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
//KVC提供属性值确认的API,它可以用来检查set的值是否正确、为不正确的值做一个替换值或者拒绝设置新值并返回错误原因。
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
//这是集合操作的API,里面还有一系列这样的API,
`- (UIImage *)deviceImage:(NSString *)deviceModel andModelVersion:(NSString *)modelVersion;` 是一个 Objective-C 方法声明,其作用是**根据设备型号(`deviceModel`)和型号版本(`modelVersion`)返回对应的设备图片(`UIImage` 对象)**。以下是详细解析: --- ### **方法功能**: 1. **输入参数** - `deviceModel`:设备型号(如 `@"iPhone13"`、`@"iPadPro"`),用于区分设备大- `modelVersion`:型号版本(如 `@"A2487"`、`@"1.0"`),用于细化同一型号的不同变体(如颜色、尺寸等)。 2. **返回值** - `UIImage *`:返回与设备匹配的图片资源,可能用于 UI 展示(如设备示意图、图标等)。 --- ### **典型实现逻辑**: ```objectivec - (UIImage *)deviceImage:(NSString *)deviceModel andModelVersion:(NSString *)modelVersion { // 1. 根据参数生成图片名称或路径 NSString *imageName = [NSString stringWithFormat:@"%@_%@", deviceModel, modelVersion]; // 2. 从资源包或缓存加载图片 UIImage *image = [UIImage imageNamed:imageName]; // 3. 如果找不到精确匹配,回退到默认逻辑(如仅用 deviceModel) if (!image) { image = [UIImage imageNamed:deviceModel]; // 或返回通用设备图片 } return image; } ``` --- ### **设计用途**: 1. **动态适配设备UI** - 不同型号/版本的设备可能需要显示不同的外观图片(如 iPhone 13 与 iPhone 13 Pro 的相机模组差异)。 2. **资源管理** - 避免硬编码图片名称,通过参数动态组合资源路径,提高可维护性。 3. **多态支持** -可重写该方法,实现自定义图片逻辑(如从网络下载设备图片)。 --- ### **注意事项**- **参数合法性**:需处理 `deviceModel` 或 `modelVersion` 为 `nil` 的情况。 - **性能优化**:频繁调用建议缓存图片,避免重复加载。 - **资源匹配**:需确保图片资源命名规则与参数组合逻辑一致(如 `@"iPhone13_A2487.png"`)。 --- ### **与其他方法的对比**: | 方法风格 | 适用场景 | |-------------------------|-----------------------------------| | 直接属性访问 `device.image` | 图片与设备对象强绑定 | | 本方法的参数化设计 | 需要灵活根据多个条件匹配资源 | | 工厂统一管理 | 全局复杂图片映射逻辑 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值