zoukankan      html  css  js  c++  java
  • iOS开发-KVC和KVO的理解

    KVC和KVO看起来很专业,其实用起来还是比较简单的,KVC(Key-value coding)可以理解为键值对编码,如果对象的基本类型,那么键值对编码实际上和get,set方法没有区别,如果是属性是另外一个对象,那么发现KVC用起来还是非常顺手,KVO(key-value observing)是键值对的观察者模式,如果对象的属性发生变更,那么会触发observeValueForKeyPath事件,KVO的这种通知特性让我们在开发的时候节省了不必要的代码,提高了开发效率。

    KVC键值对编码

    KVC的操作方法由NSKeyValueCoding协议提供,NSObject就实现了这个协议,也就是说如果对象是NSObject的子对象那么就支持KVC操作,KVC有两种操作方法,一种是设值,一种是取值,可以理解为getter和setter,不过稍微有所不同的是,设置对象值的方法中有两个,setValue:属性值 forKey:属性名(一般的设置,比如说是说设置NSString,NSNumber等基本类类型,setetValue:属性值 forKeyPath:属性路径(定义两个对象,Person和Book,Person有一个类型为Book的属性,如果需要在Person中设置Book的值,那么可以使用此方法),读取的也有两种valueForKey:属性名、valueForKeyPath:属性名。

    Person.h中的代码:

    //
    //  Person.h
    //  BugDemo
    //http://www.cnblogs.com/xiaofeixiang/
    //  Created by keso on 15/2/8.
    //  Copyright (c) 2015年 keso. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "Book.h"
    
    @interface Person : NSObject
    
    @property (strong,nonatomic) NSString *Name;
    
    @property (strong,nonatomic) Book  *Book;
    
    @end
    

    Book.h中的代码:

    //
    //  Book.h
    //  BugDemo
    //http://www.cnblogs.com/xiaofeixiang/
    //  Created by keso on 15/2/8.
    //  Copyright (c) 2015年 keso. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Book : NSObject
    
    @property (strong,nonatomic) NSString *BookName;
    
    @end
    

    Person中Book属性的类型是Book类型,看下主函数中简单调用:

          Person *person=[[Person alloc]init];
            [person setValue:@"FlyElephant" forKey:@"Name"];
            Book *book=[[Book alloc]init];
            person.Book=book;
            //路径设置
            [person setValue:@"天涯明月刀" forKeyPath:@"Book.BookName"];
            NSLog(@"%@",[person valueForKey:@"Name"]);
            NSLog(@"%@",book.BookName);
            NSLog(@"%@",[person valueForKeyPath:@"Book.BookName"]);
            NSLog(@"%@",person.Book.BookName);
    

     最终的打印结果就是FlyElephant和天涯明月刀,需要注意的是一句就是需要先赋值一个对象给Person中Book属性,不然是无法成功的:

       Book *book=[[Book alloc]init];
            person.Book=book;
    

     KVO观察者模式

    Key-Value Observing (KVO) 建立在 KVC 之上,能够观察一个对象的 KVC key path 值的变化,接下来的做的实例是在iOS中视图的ViewDidLoad中实现的,跟KVC类似,不过可以监听值的变化,实现起来很简单addObserver添加观察,observeValueForKeyPath观察变化之后的事件,最后需要销毁以下监听事件,概念就这么简单,具体的可以看一下:

    新建博主(Blogger)和Article(文章)类:

    Article.h声明:

    //
    //  Article.h
    //  KVDemo
    //http://www.cnblogs.com/xiaofeixiang/
    //  Created by keso on 15/2/8.
    //  Copyright (c) 2015年 keso. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Article : NSObject
    
    @property (strong,nonatomic) NSString *ArticleName;
    
    @end
    

    Blogger.h代码:

    //
    //  Bloger.h
    //  KVDemo
    //http://www.cnblogs.com/xiaofeixiang/
    //  Created by keso on 15/2/8.
    //  Copyright (c) 2015年 keso. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "Article.h"
    
    @interface Blogger : NSObject
    
    @property (strong,nonatomic) NSString *Name;
    
    @property (strong,nonatomic) NSString *Url;
    
    @property (strong,nonatomic) Article *MyArticle;
    
    @end
    

    然后故事板中拖一个Button和一个TextField文本框,然后点击的时候改变文本框的文字:

    首先在ViewDidLoad中添加以下代码,注意addObserver方法:

        _blogger=[[Blogger alloc]init];
        
        //设置名称
        [_blogger setValue:@"FlyElephant" forKey:@"Name"];
        //设置Url
        [self.blogger setValue:@"http://www.cnblogs.com/xiaofeixiang" forKey:@"Url"];
        //设置观察者,options通知的对象形式
        [self.blogger addObserver:self forKeyPath:@"Name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
        //设置文本
        [_myTextField setText:[_blogger valueForKey:@"Name"]];
    
       self.Article=[[Article alloc]init];
        
        [self.blogger setValue:self.Article forKey:@"MyArticle"];
        
        [self.blogger setValue:@"KVC和KVO的理解" forKeyPath:@"MyArticle.ArticleName"];
    

     按钮点击事件:

    - (IBAction)blogObserver:(id)sender {
          NSLog(@"blogObserver");
        [self.blogger setValue:@"Keso" forKey:@"Name"];
    }
    

    OC中要实现KVO则必须实现NSKeyValueObServing协议,不过NSObject已经实现了该协议,直接重写observeValueForKeyPath即可:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        NSLog(@"observeValueForKeyPath");
        if ([keyPath isEqualToString:@"Name"]) {
    //         [_myTextField setText:[_blogger valueForKey:@"Name"]];
              [_myTextField setText:_blogger.MyArticle.ArticleName];
        }
    }
    

     最后销毁监听事件:

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
        [self.blogger removeObserver:self forKeyPath:@"Name"];
    }
    

     最终实现效果:

  • 相关阅读:
    防止特殊html字符的问题(xxs攻击)方法
    asp.net 服务器Button控件使用(onclick和onclientclick使用)
    Asp:Button控件onclick事件无刷新页面提示消息
    动态添加Marquee标签,并动态赋值与属性
    asp.net 前台通过Eval()绑定动态显示样式
    asp.net 中json字符串转换
    近况
    C# fixed语句固定变量详解
    fixed说明
    Net架构必备工具列表
  • 原文地址:https://www.cnblogs.com/xiaofeixiang/p/4279731.html
Copyright © 2011-2022 走看看