成员变量、实例变量、属性的区别
@interface Person : NSObject { @public//默认为私有属性,为了让外部可以访问,需要设置为公有 int age;//成员变量 UIButton *btn;//实例变量 NSString *string; // id 是OC特有的类,本质上讲id等同于(void *)。所以id data属于实例变量。 id className; } //属性变量 @property(strong,nonatomic)NSString * name;
1.在{}中的都是成员变量
2.实例变量本质上也是成员变量,只是实例是针对类而言,实例是指类的声明,所以成员变量 = 基础数据类型变量 + 实例变量。
3.成员变量用于类内部,无需与外界接触的变量。因为成员变量不会生成setter、getter方法,所以外界无法与成员变量接触。
4.属性 会自动生成setter、getter方法。
当LLVM编译器没有发现跟实例变量相匹配的属性时,会自动生成一个带下划线的成员变量
KVC的基本使用
- 获取变量属性
根据键值获取:valueForKey: 根据路径获取:valueForKeyPath:获取未定义的值(对象中实现,防止崩溃):valueForUndefinedKey:获取数组中字典key对应的value:dictionaryWithValuesForKeys:
NSArray *array =@[@{@"name":@"123",@"age":@"3"}, @{@"name":@"1233",@"age":@"3"}, @{@"name":@"12563",@"age":@"3"}, @{@"name":@"1273",@"age":@"3"}, @{@"name":@"1323",@"age":@"3"}, @{@"name":@"1213",@"age":@"3"}]; NSArray *keys = @[@"name"];//允许多个值 //返回与接收者相关的键数组的值,这个方法会在数组中反复调用valueForKey: NSDictionary *dic = [array dictionaryWithValuesForKeys:keys]; NSLog(@"%@",dic);
- 设置变量属性
根据键值设置:setValue:forKey: 根据路径设置:setValue:forKeyPath:
设置未定义的值(对象中实现,防止崩溃):setValue:forUndefinedKey:
给对象设置对应字典里的值(字典转model):setValuesForKeysWithDictionary:
@interface Person : NSObject @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *age; -(instancetype)initWithDic:(NSDictionary *)dic; @end @implementation Person -(instancetype)initWithDic:(NSDictionary *)dic{ if (self = [super init]) { [self setValuesForKeysWithDictionary:dic]; } return self; } //如果没有实现,就会崩溃。 -(void)setValue:(id)value forUndefinedKey:(NSString *)key{ NSLog(@"没找到对应的key == %@",key); } @end NSDictionary *dic = @{@"name":@"张三",@"age":@"3",@"nickName":@"小张"}; Person *person = [[Person alloc]initWithDic:dic]; NSLog(@"name === %@,age === %@",person.name,person.age);
- 集合类型操作
NSArray *array =@[@{@"name":@"123",@"age":@"3"}, @{@"name":@"1233",@"age":@"3"}, @{@"name":@"12563",@"age":@"3"}, @{@"name":@"1273",@"age":@"3"}, @{@"name":@"1323",@"age":@"3"}, @{@"name":@"1213",@"age":@"3"}];
取和:@sum
NSNumber *sum = [array valueForKeyPath:@"@sum.name"]; NSLog(@"%@",sum);
取平均值:@avg
NSNumber *avg = [array valueForKeyPath:@"@avg.name"]; NSLog(@"%@",avg);
取数量:@count
NSNumber *count = [array valueForKeyPath:@"@count"]; NSLog(@"%@",count);
取最大值:@max、最小值@min
NSArray *array =@[@{@"name":@123,@"age":@"3"}, @{@"name":@333,@"age":@"3"}, @{@"name":@563,@"age":@"3"}, @{@"name":@1111,@"age":@"3"}, @{@"name":@756,@"age":@"3"}, @{@"name":@38459,@"age":@"3"}]; NSNumber *max = [array valueForKeyPath:@"@max.name"]; NSLog(@"%@",max);
还有其他用法待测试
@distinctUnionOfObjects
@unionOfObjects
@distinctUnionOfArrays
@unionOfArrays
@distinctUnionOfSets
valueForKey:执行流程
1.在实例中 按照顺序 搜索是否有get, , is或者_
2.如果第一步没有找到对应的方法,就看看有没有countOf, objectInAtIndex:,AtIndexes: 这几个方法,如果有找到,就会创建一个集合代理对象(应该是NSArray),并返回这个对象。
3.如果第二步还是没有,就找countOf,enumeratorOf,memberOf:这三个,返回一个NSSet对象。
4.还是没找到。如果accessInstanceVariablesDirectly的值为YES(默认就是YES), 按顺序 搜索实例变量_, _is, , is,
如果找到了,就返回结果,没找到就执行 valueForUndefinedKey:。
setValue:forKey:执行流程
1.按顺序 找set:,set:,如果有对应的方法就执行它。
2.如果没有这些方法,accessInstanceVariablesDirectly的值为YES(默认就是YES),就 按顺序 看看有没有这些值, _is, , or is,如果有,就直接给这些值的其中一个赋值。
3.如果还是没有,就走setValue:forUndefinedKey:
作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:642363427不管你是小白还是大牛欢迎入驻
,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!