当前位置: 首页 > news >正文

网站推广外贸网站备案 深圳

网站推广外贸,网站备案 深圳,wordpress搭建没域名,app开发公司成都文章目录定义四个方法用法keykeyPath设值流程验证处理不存在的key处理nil值KVC处理数值和结构体类型NSNumberNSValue简介类型使用KVC键值验证KVC处理集合简单集合运算符对象运算符KVC处理字典两个方法KVC应用定义 KVC键值编码是指iOS开发中允许作者通过key名直接访问对象的属性…

文章目录

  • 定义
    • 四个方法
    • 用法
      • key
      • keyPath
    • 设值流程
    • 验证
  • 处理不存在的key
  • 处理nil值
  • KVC处理数值和结构体类型
    • NSNumber
    • NSValue
      • 简介
      • 类型
      • 使用
  • KVC键值验证
  • KVC处理集合
    • 简单集合运算符
    • 对象运算符
  • KVC处理字典
    • 两个方法
  • KVC应用

定义

KVC键值编码是指iOS开发中允许作者通过key名直接访问对象的属性或者赋值,而不是明确调用存取方法。使用KVC键值编码可以在运行时动态的访问和修改对象的属性,而不是在编译时确定

注:在实现了访问器方法的类中使用点语法与KVC访问对象差别不大。但是在没有实现访问器方法的类中,适合使用KVC

KVC是基于NSObject的扩展来实现的,OC语言中有一个显示NSKeyValueCoding类别名,所以所有继承了NSObject的类型都可以使用KVC。除了一些没有继承NSObject的纯Swift类和结构体不支持KVC。

四个方法

- (void)setValue:(id)value forKeyPath:(NSString* )keyPath;
- (void)setValue:(id)value forKey:(NSString* )key;
- (id)valueForKeyPath:(NSString* )keyPath;
- (id)valueForKey:(NSString* )key;
  • key和keyPath的区别
    • key只接受当前类所具有的属性,不管是自己的还是从父类继承过来的
    • keyPath:除了能接受当前类的属性,还可以接受当前类的属性的属性(接受关系链)

用法

key

 Coffee* coffee = [[Coffee alloc] init];[coffee setValue:@"10000" forKey:@"price"];NSLog(@"%@", [coffee valueForKey:@"price"]);

输出结果如下:
在这里插入图片描述

keyPath

coffee.sonOfCoffee = [[SonOfCoffee alloc] init];[coffee setValue:@"white" forKeyPath:@"sonOfCoffee.color"];NSLog(@"%@", [coffee.sonOfCoffee valueForKey:@"color"]);

输出结果如下:
请添加图片描述

设值流程

  1. 按照setKey、_setKey的顺序查找方法,如果找到直接赋值
  2. 没有找到的话,则调用
+ (BOOL)accessInstanceVariablesDirectly {return YES;
/*默认返回YES表示如果没有找到Set<Key>这个存取方法的话,将按照_key、_iskey、key、iskey的顺序搜索成员,如果重写方法设置为NO,在没有找到Set<Key>后直接停止搜索了。
*/
}
  1. KVC机制会去寻找该类中以传入的"_该字符串"的成员变量,大部分时间即属性创建时自动生成的成员变量,无论该成员变量是在接口部分还是实现部分定义,无论使用的是那个访问控制符修饰,这条KVC底层都是对其进行赋值
  2. 如果仍然没有找到,系统会执行该对象的setValue:forUndefinedKey:方法,这个方法会引发一个异常,导致程序结束,valueForKey方法类似,但是获取的是getter方法的返回值,没有找到成员变量会执行valueForUndefinedKey:方法,同义也会导致·程序终止

验证

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface AUser : NSObject {@packageNSString* name;NSString* _name;
}@endNS_ASSUME_NONNULL_END
//  Created by xiaoli pop on 2025/9/10.
//#import "AUser.h"@implementation AUser {int age;
}@end
//  Created by xiaoli pop on 2025/9/9.
//#import <Foundation/Foundation.h>
#import "AUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {AUser* aUser = [[AUser alloc] init];[aUser setValue:@"strName1" forKey:@"name"];NSLog(@"name = %@", aUser->name);NSLog(@"_name = %@", aUser->_name);[aUser setValue:[NSNumber numberWithInt:10] forKey:@"age"];NSLog(@"age = %@", [aUser valueForKey:@"age"]);}return 0;
}

我们运行发现结果如下:
在这里插入图片描述

我们解释一下原因:首先我们使用KVC给属性赋值,首先查找set方法,没有找到,便按照_name、name的属性去查找。先搜索到的是_name,所以给_name赋值,name未被赋值。所以name为空。对于age成员变量来说,尽管是在类的实现部分定义的,也被赋值了

处理不存在的key

我们在使用KVC时,如果该属性没有setter、getter方法,也不存在对应的成员变量时,程序会调用setValue:forUndefinedKey: 或者valueForUndefinedKey:方法。系统默认该方法的实现是引发一个异常导致程序终止,但是我们可以重写这个方法,达到我们想要的效果


#import "AUser.h"@implementation AUser {int age;
}-(void)setValue:(id)value forUndefinedKey:(NSString *)key {NSLog(@"重写了setValue: forundefinedKey:方法");
}@end
#import <Foundation/Foundation.h>
#import "AUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {AUser* aUser = [[AUser alloc] init];[aUser setValue:@"nnnn" forKey:@"123"];}return 0;
}

输出如下结果:
在这里插入图片描述

处理nil值

假如我们在一个类中定义一个int类型的属性时,如果给他赋值为nil的话,会引发异常,因为int类型是不支持接受nil值的,也就是说,当程序尝试给某个属性赋nil时,如果该属性不能接受nil值,程序就会自动执行该对象的setNilValueForKey:方法。我们同样可以重写方法来达到我们想要的效果。示例如下:

#import "AUser.h"@implementation AUser {int age;
}- (void)setNilValueForKey:(NSString *)key {if ([key isEqualToString:@"age"]) {age = 0;} else {[super setNilValueForKey:key];}
}
//  Created by xiaoli pop on 2025/9/9.
//#import <Foundation/Foundation.h>
#import "AUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {AUser* aUser = [[AUser alloc] init];[aUser setValue:nil forKey:@"age"];NSLog(@"age = %@", [aUser valueForKey:@"age"]);}return 0;
}

输出结果如下:
在这里插入图片描述

KVC处理数值和结构体类型

valueForKey:方法总会返回一个id对象,如果原本的类型变量是值类型或者结构体类型,返回值会封装成NSNumber或者NSValue对象,这两个类会处理数字、布尔值和结构体。
在使用setValue:forKey:时,我们需要手动将值类型转换为NSNumber或者NSValue类型才能传过去。因为传入和传出都是id类型,所以需要自己保证类型正确,运行时如果错会抛出异常

NSNumber

可以使用NSNumber的数据类型:

+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

NSValue

简介

NSValue是Foundation框架的一部分,用于封装基本数据类型,如结构体和枚举,允许我们将基本数据类型存储在对象中。

类型

+ (NSValue*)valueWithCGPoint:(CGPoint)point;
+ (NSValue*)valueWithCGSize:(CGSize)size;
+ (NSValue*)valueWithCGRect:(CGRect)rect;
+ (NSValue*)valueWithCGAffineTransform:(CGAffineTransform)transform;
+ (NSValue*)valueWithUIEdgeInsets:(UIEdgeInsets)insets;
+ (NSValue*)valueWithUIOffset:(UIOffset)insetsNS_AVAILABLE_IOS(5_0);

任何结构体都可以都可以转化为NSValue对象,包括自定义的结构体

使用

我们可以使用valueWithBytes:objCType:方法来创建一个NSValue对象,这个方法接受两个参数,一个是指向数据的指针,另一个是描述数据类型的字符串

//  Created by xiaoli pop on 2025/9/9.
//#import <Foundation/Foundation.h>
#import "AUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {CGPoint point = CGPointMake(54, 45);NSValue* pointValue = [NSValue valueWithBytes:&point objCType:@encode(CGPoint)];/*@encode()返回一个OC类型的字符串编码,可以是基本数据类型,也可以是结构体类型。*/NSArray* array = [NSArray arrayWithObject:pointValue];NSLog(@"%@", array);CGRect rect = CGRectMake(10, 10, 10, 10);NSValue* pointRect = [NSValue valueWithBytes:&rect objCType:@encode(CGRect)];NSArray* array2 = [NSArray arrayWithObject:pointRect];NSLog(@"%@", array2);}return 0;
}

KVC键值验证

- (BOOL)validateValue:(inout id  _Nullable __autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError *__autoreleasing  _Nullable *)outError {if ([inKey isEqualToString:@"name"]) {NSString* name = (NSString* )*ioValue;if (name.length == 0) {if (outError) {*outError = [NSError errorWithDomain:@"MyDomain" code:1001 userInfo:@{NSLocalizedDescriptionKey:@"NAme cannot be empty."}];}return NO;}}return YES;
}

我们通过重写这个方法,就可以对属性值进行验证

#import <Foundation/Foundation.h>
#import "AUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {NSError* error = nil;NSString* name = @"";AUser* aUser = [[AUser alloc] init];if (![aUser validateValue:&name forKey:@"name" error:&error]) {NSLog(@"Validation failed: %@", error.localizedDescription);} else {[aUser setValue:name forKey:@"name"];}}return 0;
}

输出结果如下:
在这里插入图片描述

KVC处理集合

简单集合运算符

简单的集合运算符:
@avg:平均值
@count:总个数
@max: 最大值
@min:最小值
@sum:总量


#import <Foundation/Foundation.h>
#import "AUser.h"
#import "BUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {BUser* b1 = [BUser new];b1.name = @"小李";b1.age = 10;BUser* b2 = [BUser new];b2.name = @"小吴";b2.age = 20;BUser* b3 = [BUser new];b3.name = @"小杨";b3.age = 30;NSArray* array = [NSArray arrayWithObjects:b1, b2, b3, nil];NSNumber* sum = [array valueForKeyPath:@"@sum.age"];NSLog(@"sum = %@", sum);NSNumber* avg = [array valueForKeyPath:@"@avg.age"];NSLog(@"avg = %@", avg);NSNumber* count = [array valueForKeyPath:@"@count.age"];NSLog(@"count = %@", count);NSNumber* min = [array valueForKeyPath:@"@min.age"];NSLog(@"min = %@", min);NSNumber* max = [array valueForKeyPath:@"@max.age"];NSLog(@"max = %@", max);}return 0;
}

输出结果如下:
在这里插入图片描述

对象运算符

以数组的形似返回。有下面几种情况

  1. unionOfObjects: 不去重
  2. distinctUnionOfObjects: 去重
  3. unionOfArrays:不去重
  4. distinctUnionOfArrays:去重
    后面两种是针对二维数组的
    示例:
#import <Foundation/Foundation.h>
#import "AUser.h"
#import "BUser.h"
int main(int argc, const char * argv[]) {@autoreleasepool {BUser* b1 = [BUser new];b1.name = @"小李";b1.age = 10;BUser* b2 = [BUser new];b2.name = @"小吴";b2.age = 20;BUser* b3 = [BUser new];b3.name = @"小杨";b3.age = 30;NSArray* array = [NSArray arrayWithObjects:b1, b2, b3, nil];NSArray* nameArray = [array valueForKeyPath:@"@unionOfObjects.name"];for (NSString* nameStr in nameArray) {NSLog(@"%@",nameStr);}}return 0;
}

输出结果如下:
在这里插入图片描述

KVC处理字典

两个方法

- (NSDictionary<NSString *,id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys {//输入一组key,返回这组key对应的属性,再组成一个字典返回
}
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues {//用来修改Model中对应的属性
}

示例:

@property (nonatomic, copy)NSString* country;
@property (nonatomic, copy)NSString* province;
@property (nonatomic, copy)NSString* city;
@property (nonatomic, copy)NSString* district;
int main(int argc, const char * argv[]) {@autoreleasepool {BUser* bUser = [BUser new];bUser.country = @"China";bUser.province = @"ShanXi";bUser.city = @"Ankang";bUser.district = @"HanBin";NSArray* array = @[@"country", @"province", @"city", @"district"];NSDictionary* dict = [bUser dictionaryWithValuesForKeys:array];NSLog(@"%@", dict);NSDictionary* modifyDict = @{@"country" : @"USA", @"province" : @"califonia", @"city" : @"ooo", @"district" : @"ppp"};[bUser setValuesForKeysWithDictionary:modifyDict];NSLog(@"country = %@, province = %@ , city = %@", bUser.country, bUser.province, bUser.city);}return 0;
}

在这里插入图片描述

KVC应用

  1. 动态的取值设值
  2. 使用KVC访问和修改私有变量
  3. Model和字典之间的转化
  4. 修改一些控件的内部属性
  5. 操作集合
http://www.dtcms.com/a/522171.html

相关文章:

  • 外贸网站模板建立建设网站 托管 费用
  • 网站建设备案是什么意思一站传媒seo优化
  • 网站开发平台建设今天贵阳最新头条新闻
  • 石狮住房和城乡建设局网站找阿里巴巴购买做网站的软件
  • 北京建设网站网站网站开发 实时更新
  • pos网站源码建设工程培训
  • 合肥商务科技学校网站建设做旅游网站的目的和意义
  • 南宁网站推广¥做下拉去118cr网站建设怎么用长尾做标题
  • 深圳找人做网站网站改版建设 有哪些内容
  • 做网站如何防止被骗python3 网站建设
  • 宁波专业网站建设公司新泰网页定制
  • 不用代码做网站的工具包头哪里做网站
  • 苏州区网站建设北京模型设计制作
  • 句容网站制作哪家好国内类似wordpress
  • 天津环保网站建设概念网站开发项目拖延周期
  • iis网站物理路径确定网站推广目标
  • 网易那个自己做游戏的网站是什么原因东莞阳光网投诉查看
  • flash 3d 网站源码住房建设网站
  • HarmonyOS 项目入门:构建跨设备智能应用的强大框架
  • 法律行业网站建设校园电商平台网站建设
  • dw做网站弊端阿里logo设计平台
  • 衡水网站建设制作html音乐播放器代码
  • 算法面经常考题整理(3)大模型
  • 柯城网站建设新版lnmp安装wordpress
  • 甘肃建设厅网站二级建造师报名时间香河县住房和城乡建设局网站
  • 购物网站开发流程图莱州 网站制作
  • 做网站建设话术找人做网站排名优化
  • 怎么制作网站源码网站建设工具
  • 东莞网站设计智能 乐云践新wordpress自动发现
  • 网站跳转到另外一个网站怎么做软件开发工具是什么意思