KVC

2018-09-03  本文已影响3人  梓华

参考 https://www.jianshu.com/p/4748ef75126a

Key

/**
 *  @public 可以在任何地方访问
 *  @protected 可以在当前类和其子类里访问
 *  @private 只能在当前类里访问
 */
@interface Teacher : NSObject
{
    @private
    int _age;
}

@property (nonatomic, strong, readonly) NSString *name;
@property (nonatomic, assign, getter = isMale) BOOL male;

/**
 *  打印
 */
- (void)log;

@end
        Teacher *teacher = [Teacher new];
        
        //age是私有private变量和name是只读readonly变量 
        //teacher.age;
        //teacher.name = @"haha";
        
        [teacher log];
    
        [teacher setValue:@"Jack" forKey:@"name"];
        
        [teacher setValue:@24 forKey:@"age"];

        [teacher setValue:@1 forKey:@"male"];
        
        [teacher log];

        NSLog(@"name: %@", [teacher valueForKey:@"name"]);

        NSLog(@"age: %d", [[teacher valueForKey:@"age"] intValue]);
        
        NSLog(@"male: %d", [[teacher valueForKey:@"male"] boolValue]);

KeyPath(对象包含了其他对象)

@class Student;

@interface Teacher : NSObject

@property (nonatomic, strong) Student *student;

@end
@interface Student : NSObject
{
    @private
    NSString *_name;
}

- (void)log;

@end
        Teacher *teacher = [Teacher new];
        
        Student *student = [Student new];
        
        [student log];
        
        [student setValue:@"Kobe" forKey:@"name"];
        
        [teacher setValue:student forKey:@"student"];
        
        NSString *studentName = [teacher valueForKeyPath:@"student.name"];
        NSLog(@"Student name: %@",studentName);
        
        [teacher setValue:@"James" forKeyPath:@"student.name"];

        [student log];
    /*
     如果你不小心错误的使用了key而非keyPath的话,KVC会直接查找
     student.name这个属性,很明显,这个属性并不存在。所以会再调用
     UndefinedKey相关方法。而KVC对于keyPath是搜索机制第一步就是分离
     key,用小数点.来分割key,然后再像普通key一样按照先前介绍的顺序搜
     索下去。如果没有小数点,就直接向普通key来搜索。
     */
集合
@class Student;

@interface Teacher : NSObject

@property (nonatomic, strong) Student *student;

- (instancetype)initWithStudent:(Student *)student;

@end
@class Book;

@interface Student : NSObject

@property (nonatomic, strong) NSArray<Book *> *bookList;

- (instancetype)initWithBookList:(NSArray *)bookList;

@end
@interface Book : NSObject

@property (nonatomic, copy) NSString *name;

@property (nonatomic, assign) float price;

- (instancetype)initWithName:(NSString *)name price:(float)price;

@end
teacher 有property student
student 有NSArray<Book *> *bookList
        NSMutableArray *bookList = [NSMutableArray array];
        
        for(int i = 0; i <= 10; i++)
        {
            Book *book = [[Book alloc] initWithName:[NSString stringWithFormat:@"book%d",i] price:i*10];
            
            [bookList addObject:book];
        }
        
        Student *student = [[Student alloc] initWithBookList:bookList];
        
        Teacher *teacher = [[Teacher alloc] initWithStudent:student];

        for(Book *book in [student valueForKey:@"bookList"])
        {
            NSLog(@"bookName:%@ \t price:%f", book.name, book.price);
        }
        
        NSLog(@"All book name: %@", [teacher valueForKeyPath:@"student.bookList.name"]);
        NSLog(@"All book name: %@", [student valueForKeyPath:@"bookList.name"]);
        
        NSLog(@"All book price: %@", [teacher valueForKeyPath:@"student.bookList.price"]);
        NSLog(@"All book price: %@", [student valueForKeyPath:@"bookList.price"]);
        
        NSLog(@"count of book price: %@",[student valueForKeyPath:@"bookList.@count.price"]);
        NSLog(@"min of book price: %@",[student valueForKeyPath:@"bookList.@min.price"]);
        NSLog(@"max of book price: %@",[student valueForKeyPath:@"bookList.@max.price"]);
        NSLog(@"sum of book price: %@",[student valueForKeyPath:@"bookList.@sum.price"]);
        NSLog(@"avg of book price: %@",[student valueForKeyPath:@"bookList.@avg.price"]);

字典

{
    "product":
            {
              "name": "手机",
              "categoryList": [
                               {
                               "name": "iPhone",
                               "id": "1",
                               "price": "100.03",
                               "image": "www.iPhone.com"
                               },
                               {
                               "name": "三星",
                               "id": "2",
                               "price": "80",
                               "image": "www.samsung.com"
                               },
                               {
                               "name": "小米",
                               "id": "3",
                               "price": "60",
                               "image": "www.xiaomi.com"
                               },
                               {
                               "name": "华为",
                               "id": "4",
                               "price": "40.5",
                               "image": "www.huawei.com"
                               }
                               ]
            }
}
@interface CategoryList : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *image;
@property (nonatomic, copy) NSString *productId;
@property (nonatomic, assign) float price;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@end
@implementation CategoryList

- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
    if(self = [super init])
    {
        [self setValuesForKeysWithDictionary:dictionary];
    }
    
    return self;
}

- (void)setValue:(id)value forKey:(NSString *)key
{
    //key为"price" ("price": "100.03") value为字符串 price为float
    if([key isEqualToString:@"price"])
    {
        self.price = [value floatValue];
    }
    else
    {
        [super setValue:value forKey:key];
    }
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    //key为"id" ("id": "1") value为字符串 赋值给productId
    if([key isEqualToString:@"id"])
    {
        self.productId = value;
    }
    else
    {
        [super setValue:value forUndefinedKey:key];
    }
}

@end
@interface Product : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSMutableArray *categoryList;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@end

- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
    if(self = [super init])
    {
        [self setValuesForKeysWithDictionary:dictionary];
    }
    
    return self;
}

- (void)setValue:(id)value forKey:(NSString *)key
{
    //key为categoryList value是数组 数组里每个值是字典 
    if([key isEqualToString:@"categoryList"])
    {
        self.categoryList = [NSMutableArray array];
        
        for(NSMutableDictionary *dict in value)
        {
            CategoryList *list = [[CategoryList alloc] initWithDictionary:dict];
            
            [self.categoryList addObject:list];
        }
    }
    else
    {
        [super setValue:value forKey:key];
    }
}
    NSString *path = [[NSBundle mainBundle] pathForResource:@"product" ofType:@"json"];
    
    NSData *data = [NSData dataWithContentsOfFile:path];
    
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
    
    NSLog(@"%@", dict);
    
    NSDictionary *dataDict = dict[@"product"];
    
    Product *p = [[Product alloc] initWithDictionary:dataDict];
    
    NSLog(@"%@ %@", p.name, p.categoryList);
    
    for(CategoryList *list in p.categoryList)
    {
        NSLog(@"%@ == %@ == %@ == %.2f", list.name, list.image, list.productId, list.price);
    }

修改属性

    //在iOS6.0之前 可以通过KVC来设置_placeholderLabel的属性值
    [_textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
    [_textField setValue:[UIFont systemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
    //iOS 6.0之后 提供的attributedPlaceholder属性
    NSString *holderText = @"输入密码";
    
    NSMutableAttributedString *placeholder = [[NSMutableAttributedString alloc] initWithString:holderText];
    
    [placeholder addAttribute:NSForegroundColorAttributeName
                        value:[UIColor redColor]
                        range:NSMakeRange(0, holderText.length)];
    
    [placeholder addAttribute:NSFontAttributeName
                        value:[UIFont boldSystemFontOfSize:16]
                        range:NSMakeRange(0, holderText.length)];
    
    _textField.attributedPlaceholder = placeholder;
    [_pageControl setValue:[UIImage imageNamed:@"selected"] forKey:@"_currentPageImage"];
    [_pageControl setValue:[UIImage imageNamed:@"unselected"] forKey:@"_pageImage"];
上一篇下一篇

猜你喜欢

热点阅读