KVC和KVO

KVC和KVO
今天在這里給大家詳解一下KVC和KVO的用法, 在這里首先給大家介紹一下KVC的用法,雖然他倆看似只差一個(gè)字母但,但其實(shí)兩種放法的機(jī)制相差很大,千萬(wàn)不要被表象所蒙騙哦, 下面分別介紹了兩種機(jī)制的使用方式, 理解之后你就明白, 他倆一毛錢關(guān)系也沒(méi)有哦 ^- -^
KVC
KVC(鍵值編碼,是KeyValue Coding的簡(jiǎn)稱),它是一種可以直接通過(guò)字符串的名字(key)來(lái)訪問(wèn)類屬性的機(jī)制.使用該機(jī)制不需要調(diào)取實(shí)例變量就可以訪問(wèn)對(duì)象屬性,并對(duì)屬性進(jìn)行賦值.在iOS開(kāi)發(fā)中, KVC經(jīng)常會(huì)被使用,在給Model類進(jìn)行賦值時(shí),你會(huì)經(jīng)常用到KVC, 如果你還不知道Model,請(qǐng)自行補(bǔ)習(xí).下面的實(shí)例清單會(huì)涉及Model類.

實(shí)例清單1.1 KVC的最基礎(chǔ)用法(setValue:forKey:):

//Person類.h文件內(nèi)容
#import <Foundation/Foundation.h>
@class Student;
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@end
//VC中.m內(nèi)容

Person *per = [[Person alloc] init];
    [per setValue:@"火星人" forKey:@"name"];
    NSLog(@"%@", per.name);

實(shí)例清單1.2 KVC的第二種用法(setValuesForKeysWithDictionary:):

#import <Foundation/Foundation.h>
@interface Person : NSObject
// 自定義Model(Person)類.h文件內(nèi)容/此.m文件無(wú)內(nèi)容(在真正的開(kāi)發(fā)中.m中是有內(nèi)容, 在這里為了減少我的工作量,我lazy一下)

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *phoneNumber;
@property (nonatomic, strong) NSString *address;
@end
// VC中的.m文件中內(nèi)容
// 定義一個(gè)字典, 在這里請(qǐng)注意,字典中Key值要和Model類中屬性名一致,不然會(huì)出現(xiàn)問(wèn)題,把出錯(cuò)的話,就復(fù)制粘貼吧! (^-#-^)
NSDictionary *personDic = @{@"name" :@"你是誰(shuí)", @"phoneNumber" :@"1314512521", @"address" :@"國(guó)際空間站"};
    Person *per = [[Person alloc] init];
    
//注意:這只是KVC中的一種用法(下面會(huì)把中的用法都介紹一下)
    [per setValuesForKeysWithDictionary:personDic];

實(shí)例清單1.3 KVC的第三種用法(可能會(huì)失效,原因未知, 有待讀者研究)(setValue:forKeyPath:):

// Person.h類文件
#import <Foundation/Foundation.h>
@class Student;
@interface Person : NSObject
@property (nonatomic, strong) Student *stu;
@end

// Student.h類文件  
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, strong) NSString *sex;
@end

//vc.m文件
#import "ViewController.h"
#import "Person.h"
#import "student.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Person *per = [[Person alloc] init];
    
    //關(guān)鍵路徑賦值
    [per setValue:@"male" forKeyPath:@"stu.sex"];
    Student *stu = [[Student alloc] init];
    NSLog(@"%@", stu);
}

KVO
重點(diǎn)來(lái)了,KVO的時(shí)間到了,KVO的全稱叫(Key-value observing),在我理解看來(lái),就是一種監(jiān)聽(tīng)機(jī)制,能夠?qū)崟r(shí)的監(jiān)聽(tīng)關(guān)鍵Key值得變化,現(xiàn)在你可能不明白這個(gè)Key到底是神魔玩意, 先不要著急,繼續(xù)讀下去,在這我先舉幾個(gè)例子,比如:UIscrollView中屬性contentOffset, 自定義的BOOL屬性, UIView及子類的backgroundColor屬性等等都可以作為Key,即觀察的對(duì)象.廢話不多說(shuō)了,實(shí)例才能證明一切.
聲明:如果想實(shí)現(xiàn)下列清單中的案例請(qǐng)粘貼到工程中就可以了,具體的實(shí)現(xiàn)可能使你更加的了解KVO -%-

實(shí)例清單如下:

//自定義的TitleView(網(wǎng)易新聞的文字橫條)

//TitleView.h文件
#import <UIKit/UIKit.h>
@interface TitleView : UIView
@property (nonatomic, retain) NSArray *titles;
@end

//TitleView.m文件
#import "TitleView.h"
@interface TitleView ()
@end
@implementation TitleView
#pragma mark - override
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self createSubviews];
    }
    return self;
}

- (void)setTitles:(NSArray *)titles {
    for (int i = 0; i < 5; i++) {
        [self.subviews[i] setTitle:titles[i] forState:UIControlStateNormal];
    }
}

- (void)createSubviews {
    for (int i = 0; i < 5; i++) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];      
        [button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
        button.frame = CGRectMake(CGRectGetWidth(self.bounds) / 5 * i, 0, CGRectGetWidth(self.bounds) / 5, CGRectGetHeight(self.bounds));
        [self addSubview:button];
    }
}
// 當(dāng)然自定義TitleView不是重點(diǎn)啦, 重點(diǎn)來(lái)啦
@interface ViewController () <UICollectionViewDelegate, UICollectionViewDataSource,
UIScrollViewDelegate>

@property (nonatomic, retain) UIView *viewOfRedline;
@property (nonatomic, retain) UICollectionView *collectionView;
@property (nonatomic, retain) TitleView *viewOfTitle;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    [self createViewOfRedLine];
    [self createCollectionView];
    [self createTitleView];
}

//不是重點(diǎn)哦
- (void)createViewOfRedLine {
    self.viewOfRedline = [[UIView alloc] initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds) / 5, 2)]; 
    [self.view addSubview:self.viewOfRedline];
    self.viewOfRedline.backgroundColor = [UIColor redColor];
}

// 不是重點(diǎn)哦
- (void)createCollectionView { 
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    layout.itemSize = CGSizeMake(CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - 66);
    layout.minimumInteritemSpacing = 0;
    layout.minimumLineSpacing = 0;
    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 66, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - 66) collectionViewLayout:layout];
    
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;
    [self.view addSubview:self.collectionView];
    
    // 注冊(cè)cell
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"pool"];
    self.collectionView.pagingEnabled = YES;
    
// KVO 觀察collectionView的offset //注意:次步是重點(diǎn) 
    [self.collectionView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];    
}

// 不是重點(diǎn)
- (void)createTitleView {
    self.viewOfTitle = [[TitleView alloc] initWithFrame:CGRectMake(0, 32, CGRectGetWidth(self.view.bounds), 32)];
    self.viewOfTitle.titles = @[@"頭條", @"熱點(diǎn)", @"財(cái)經(jīng)", @"新聞", @"汽車"];  
    [self.view addSubview:self.viewOfTitle]; 
}

// KOV的實(shí)現(xiàn),事件處理都在這里進(jìn)行處理, 這是重點(diǎn)哦, 好好理解一下吧
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {

//objectForKey:@"new" 中的只能寫@"new"(新的值, 監(jiān)聽(tīng)的Key的變化的值) 或者寫 @"old"(舊的值, 監(jiān)聽(tīng)Key變化之前的值)
// 在這里我們獲取新值(變化后的值)
    CGFloat x = [[change objectForKey:@"new"] CGPointValue].x / 5.0f;
    self.viewOfRedline.frame = CGRectMake(x, 64, CGRectGetWidth(self.view.bounds) / 5, 2); 
}

// UIScrollView的協(xié)議方法之一
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 5;
}

// UIScrollView的協(xié)議方法之一
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"pool" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:arc4random() % (256) / 255.0f green:arc4random() % (256) / 255.0f blue:arc4random() % (256) / 255.0f alpha:1]; 
    return cell;
}

 // 改變標(biāo)題的顏色
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSInteger index = scrollView.contentOffset.x / 5.0f / (CGRectGetWidth(self.view.bounds) / 5);
    for (UIButton *button in self.viewOfTitle.subviews) {
        [button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
    }
    [self.viewOfTitle.subviews[index] setTitleColor:[UIColor redColor] forState:UIControlStateNormal];    
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概念 先來(lái)看看概念,Key-value coding (KVC) 和 key-value observing (K...
    wuwy閱讀 1,586評(píng)論 0 1
  • 目錄:1.KVC用法;2.KVC和對(duì)象的setter、getter方法的區(qū)別;3.key和keyPath的區(qū)別;4...
    倫倫子_f7b3閱讀 686評(píng)論 0 1
  • 什么是KVC和KVO??jī)烧咧g有何關(guān)系 KVC : 鍵值編碼,是Key Value Coding 的簡(jiǎn)稱,coco...
    蘭章海晏閱讀 3,770評(píng)論 0 3
  • 在編程中,最常見(jiàn)的就是程序的流程取決于你所使用的各種變量和屬性的值,根據(jù)變量和屬性的值確定后面運(yùn)行的代碼,有時(shí)會(huì)檢...
    pro648閱讀 1,772評(píng)論 2 27
  • 在iOS開(kāi)發(fā)中,我們常常用到鍵值編碼KVC和鍵值監(jiān)聽(tīng)KVO兩個(gè)東東,今天小編和大家分享的就是這兩個(gè)東東在應(yīng)用開(kāi)發(fā)中...
    突然自我閱讀 1,081評(píng)論 2 3

友情鏈接更多精彩內(nèi)容