您的位置:首页 > 产品设计 > UI/UE

KVO(Key Value Observing)

2015-07-14 08:44 477 查看
*KVO可以监听某个对象属性的改变

原理:只要给一个对象注册一个监听,那么在运行时, 系统就会自动给该对象生成一个子类对象,并且重写自动生成的子类对象的被监听属性的set方法,然后在set方法中通知监听者

*

定义一个HSPerson类

//
//  HSPerson.h
//  KVC
//
//  Created by hans on 15/7/13.
//  Copyright © 2015年 hans. All rights reserved.
//

#import <Foundation/Foundation.h>
@class HSCar;

@interface HSPerson : NSObject
{
@public
    int _age;
}

/** 名字 */
@property (nonatomic, copy) NSString *name;

/** 年龄 */
@property (nonatomic, assign) int age;

@end


在ViewController实现

//
//  ViewController.m
//  KVO
//
//  Created by hans on 15/7/14.
//  Copyright © 2015年 hans. All rights reserved.
//

#import "ViewController.h"
#import "HSPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    HSPerson *person = [HSPerson new];
    person.name = @"hans";
    person.age = 23;

    /*
     第一个参数: 告诉系统哪个对象监听
     第二个参数: 监听当前对象的哪个属性
     第三个参数: 监听到属性改变之后,传递什么值
     第四个参数: 需要传递的参数 (这个参数不是传递给属性的)
     */
    [person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

    person.name =@"汉斯哈哈哈";
//    输出:
//    2015-07-14 08:24:18.697 KVO[55716:952095] keyPath = name, object = <HSPerson: 0x7fdd00d2dbc0> , change = {
//        kind = 1;
//        new = "\U6c49\U65af\U54c8\U54c8\U54c8";
//        old = hans;
//    }, context = (null)

    // 注意: KVO只能监听通过set方法修改的值
    // 不会被监听到
    person->_age = 100;

    // 注意: 如果使用KVO监听某个对象的属性, 当对象释放之前一定要移除监听
    //  reason: 'An instance 0x7f9483516610 of class Person was deallocated while key value observers were still registered with it.
    // 从person对象上移除self对它的age属性的监听
    [person removeObserver:self forKeyPath:@"name"];

}

// 只要监听到属性的改变就会调用
// keyPath: 被监听的属性名称
// object : 被监听的对象
// context: 注册监听的时候传入的值
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context
{
    NSLog(@"keyPath = %@, object = %@ , change = %@, context = %@", keyPath, object, change, context);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: