年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2649|回复: 0

KVO 的基本理解

[复制链接]
  • TA的每日心情

    2024-10-15 10:05
  • 签到天数: 372 天

    [LV.9]以坛为家II

    发表于 2014-5-17 14:01:19 | 显示全部楼层 |阅读模式
    本帖最后由 Sian 于 2014-5-31 08:57 编辑

    KVO概述:
    KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。
    简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。

    KVO的优点:
    当有属性改变,KVO会提供自动的消息通知。这样开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。
    这是KVO机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。
    开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可以在工程里使用。
    其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同 一个属性,以及相关的值。

    使用步骤如下:
    1. 注册,指定被观察者的属性,
    2. 实现回调方法
    3. 触发回调方法
    4. 移除观察

    KVO使用例子代码如下:

    ###############Model(模型)###############
    #import <Foundation/Foundation.h>
    @interface Music : NSObject {
        // 监听的属性
        NSString *musicName;
    }
    @end

    #import "Music.h"
    @implementation Music
    @end

    ###############ViewController(视图控制器)###############
    #import <UIKit/UIKit.h>
    @class Music;
    @interface ViewController : UIViewController {
        Music *music;   
    }
    @property (nonatomic, retain) Music *music;
    @end

    @implementation ViewController
    @synthesize music;

    #pragma mark - View lifecycle

    - (void)viewDidLoad
    {
        [super viewDidLoad];
       
        music = [[Music alloc] init];
       
        // 添加观察者  注册当属性发生改变的时候被调用的
        [music addObserver:self forKeyPath:@"musicName" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

       
        // UILabel控件
        UILabel *musicLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 150, 280, 21)];
        musicLabel.font = [UIFont fontWithName:@"ArialMT" size:18];
        musicLabel.textColor = [UIColor redColor];
        musicLabel.tag = 100;
        [self.view addSubview:musicLabel];
        [musicLabel release];
       
        // UITextField控件
        UITextField *musicTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, 280, 21)];
        musicTextField.font = [UIFont fontWithName:@"ArialMT" size:18];
        musicTextField.placeholder = @"Please enter some words.";
        musicTextField.backgroundColor = [UIColor whiteColor];
       
        // UITextField输入内容时候调用
        [musicTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
       
        [self.view addSubview:musicTextField];
        [musicTextField release];

        self.view.backgroundColor = [UIColor grayColor];
    }

    - (void)textFieldDidChange:(id)sender {
        UITextField *textField = (UITextField *)sender;
        NSLog(@">>>>>>>>>>>>>>>%@",textField.text);
        // 修改正在监听的属性,将调用下面回调方法
        [music setValue:textField.text forKey:@"musicName"];
    }

    // 只要Music类的"musicName"属性发生的变化都会触发到以下的方法
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        UILabel *label = (UILabel *)[self.view viewWithTag:100];
        // 如果改变的属性是"musicName"
        if ([keyPath isEqualToString:@"musicName"]) {
            // 将 当前的musicName属性的值 赋值给UILabel
            label.text = [music valueForKey:@"musicName"];
            // 输出改变前的值
            NSLog(@"old musicName is %@",[change objectForKey:@"old"]);
            // 输出改变后的值
            NSLog(@"new musicName is %@",[change objectForKey:@"new"]);        
        }
    }

    #pragma mark - Memory Management
    - (void)dealloc {
        // 移除观察者
        [music removeObserver:self forKeyPath:@"musicName"];

        [music release];
        [super dealloc];
    }

    参考链接:http://blog.sina.com.cn/s/blog_621403ef0100ywc9.html


    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-12-4 16:50 , Processed in 0.045851 second(s), 22 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表