KVC

作者: 梓华 | 来源:发表于2018-09-03 15:09 被阅读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"];
    

    相关文章

      网友评论

          本文标题:KVC

          本文链接:https://www.haomeiwen.com/subject/mkjbwftx.html