iOS设计模式 —— KVC
2024-08-15 23:26:50 223人阅读
刨根问底KVC KVC 全称 key valued coding 键值编码
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性.JAVA,C#都有这个机制。ObjC也有,所以你根部不必进行任何操作就可以进行属性的动态读写,就是KVC。
KVC的操作方法由NSKeyValueCoding提供,而他是NSObject的类别,也就是说ObjC中几乎所有的对象都支持KVC操作。
Person.h
123456789101112 @interface Person : NSObject{ int weight;}@property(nonatomic,readonly,copy) NSString *name;@property(nonatomic,readonly, assign) int age;@property(nonatomic,strong) Dog * dog;@property(nonatomic,assign) id ID;-(instancetype)initWithDict:(NSDictionary *)dict;@end
Person.m
1234567891011121314151617181920212223242526272829303132333435 @implementation Person{ int _height;}-(instancetype)initWithDict:(NSDictionary *)dict{ if (self=[super init]) {
main.m
1234567891011121314151617181920212223242526272829303132 Person * p1 = [[Person alloc]init];Dog * d1 = [[Dog alloc] init];p1.dog = d1;
KVC查找属性的顺序 用@property定义的属性的key值 setter方法的key值 直接访问成员变量,先找key,如果找不到,再找_key 以上三种都未找到就会调用- (void)setValue:(id)value forUndefinedKey:(NSString *)key 方法。 如果没有重写setValue:forUndefinedKey程序会马上崩溃。 注意:KVC可以访问成员变量,无论是否提供getter/setter方法,无论可见性是怎样,是否有readonly修饰。
setValue:forUndefinedKey与valueForUndefinedKey的应用 KVC的主要用途无非是ORM映射,就是将dictionary转换成model,但有些服务器返回的字段有可能是oc的关键字比如‘id’,’description’等。如上代码举得id的例子,我们无法让@property后面key值为id,于是使用大写的ID代替,KVC是区分大小写的我们不用担心。这时我们只需在setValue:forUndefinedKey把id的key值赋值给ID的key值,就可以避免关键字的尴尬。
KVC的逆向使用 12345678910111213141516 Person * p1 = [[Person alloc]init];[p1 setValue:@"170" forKey:@"height"];[p1 setValue:@"70" forKey:@"weight"];[p1 setValue:@"11111" forKey:@"id"]; NSArray * arr = @[@"height",@"weight",@"id"];NSDictionary * dict = [p1 dictionaryWithValuesForKeys:arr];NSLog(@"%@",dict);log日志:{ height = 170; id = 11111; weight = 70;}
NSArray/NSSet等都支持KVC 1234567891011121314151617181920 Person * p1 = [[Person alloc]init];Dog * d1 = [[Dog alloc] init];d1.name = @"iPhone";p1.dog = d1; Person * p2 = [[Person alloc]init];Dog * d2 = [[Dog alloc] init];d2.name = @"ios";p2.dog = d2;NSArray *persons=@[p1,p2]; NSArray *arrayM=[persons valueForKeyPath:@"dog.name"];NSLog(@"%@",arrayM);log日志:( iPhone, ios)
KVC计算 12345678910111213141516171819202122232425 Person * person = [[Person alloc] init];NSMutableArray * books = [NSMutableArray array];for (int i = 0; i < 10; i++) { Book * book = [[Book alloc] init]; book.price = i; [books addObject:book];}person.books = books;NSNumber *bookCount = [person valueForKeyPath:@"books.@count"];NSLog(@"book count :%@", bookCount);NSNumber *sum = [person valueForKeyPath:@"books.@sum.price"];NSLog(@"sum :%@", sum);NSNumber *avg = [person valueForKeyPath:@"books.@avg.price"];NSLog(@"vag :%@", avg);NSNumber *min = [person valueForKeyPath:@"books.@min.price"];NSLog(@"min :%@", min);NSNumber *max = [person valueForKeyPath:@"books.@max.price"];NSLog(@"max :%@", max);
KVC底层实现 123456789 比如说如下的一行KVC的代码: [person setValue:@"dahuan" forKey:@"name"]; 就会被编译器处理成: SEL sel = sel_get_uid ("setValue:forKey:");IMP method = objc_msg_lookup (person->isa,sel);method(person, sel, @"dahuan", @"name");
KVC与runtime应用 123456789101112131415161718192021222324252627282930313233343536373839404142 #import "MyModel.h"#import <objc/runtime.h> @implementation MyModel
最后附苹果KVC官方文档:
https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/KeyValueCoding.html
另外.....
我的愿望是.......
世界和平.........
iOS设计模式 —— KVC
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉:
投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。
×
https://www.u72.net/daima/bsk6.html