键值监听KVO

在IOS中都有一种双向绑定机制,如果数据模型修改了之后会立即反映到UI视图上,它叫做Key Value Observing(简称KVO)。KVO其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。

在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过幸运的是NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。

Object-C

在ObjC中使用KVO操作常用的方法如下:
1. 注册指定Key路径的监听器: addObserver: forKeyPath: options: context:
2. 删除指定Key路径的监听器: removeObserver: forKeyPath、removeObserver: forKeyPath: context:
3. 回调监听: observeValueForKeyPath: ofObject: change: context:
KVO的使用步骤也比较简单:
1.通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
2.重写监听器的observeValueForKeyPath: ofObject: change: context:方法

模型数据

User.h

//
//  User.h
//  KVO
//
//  Created by yangjun on 15/10/10.
//  Copyright © 2015年 六月. All rights reserved.
//

#import <Foundation/Foundation.h>

/** 用户*/
@interface User : NSObject

@property (nonatomic, copy) NSString *userName; ///< 用户名

@end

XCTestCase测试

//
//  KVOTests.m
//  KVOTests
//
//  Created by yangjun on 15/10/10.
//  Copyright © 2015年 六月. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "User.h"

@interface KVOTests : XCTestCase
{
    User *_user;
}

@end

@implementation KVOTests

- (void)setUp {
    [super setUp];
    _user = [[User alloc] init];
    [_user addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew context:nil];// 添加监听

}

- (void)tearDown {
    [super tearDown];
    _user = nil;
}

- (void)testExample {
    _user.userName = @"yangjun";
    [_user removeObserver:self forKeyPath:@"userName"];// 取消监听
    _user.userName = @"IOS";
}

#pragma mark 监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if ([@"userName" isEqualToString:keyPath]) {// 这里只处理userName属性
        NSLog(@"userName:%@; change:%@", ((User *)object).userName, change);
    }
}

@end

输出

2015-10-10 15:23:47.660 KVO[10344:789286] userName:yangjun; change:{
    kind = 1;
    new = yangjun;
}

Swift

在Swift中使用KVO操作常用的方法如下:
1. 注册指定Key路径的监听器:addObserver(observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions, context: UnsafeMutablePointer<Void>)
2. 删除指定Key路径的监听器:removeObserver(observer: NSObject, forKeyPath keyPath: String)
3. 回调监听:override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)
KVO的使用步骤也比较简单:
1.通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
2.重写监听器的observeValueForKeyPath: ofObject: change: context:方法

模型

User.swift

//
//  User.swift
//  KVO
//
//  Created by yangjun on 15/10/10.
//  Copyright © 2015年 六月. All rights reserved.
//

import Foundation

/// 用户
class User: NSObject {

    /// 用户名
    dynamic var userName:String?

    override init() {
        userName = ""
    }

}

XCTestCase测试

//
//  KVOTests.swift
//  KVOTests
//
//  Created by yangjun on 15/10/10.
//  Copyright © 2015年 六月. All rights reserved.
//

import XCTest

/// KVO测试
class KVOTests: XCTestCase {

    /// 用户
    var user:User!;

    // MARK: 开始
    override func setUp() {
        super.setUp()
        self.user = User()
        self.user.addObserver(self, forKeyPath: "userName", options: NSKeyValueObservingOptions.New, context: nil)// 监听(KVO的属性必须设置dynamic)
    }

    // MARK: 结束
    override func tearDown() {
        super.tearDown()
        self.user.removeObserver(self, forKeyPath: "userName")
        self.user.userName = "YangJun"
    }

    // MARK: 测试用例
    func testExample() {
        self.user.userName = "阳君"
    }

    // MARK: - 监听
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if "userName" == keyPath {
            print("userName:\((object as? User)?.userName); change:\(change)")
        }
    }

}

输出

userName:Optional("阳君"); change:Optional(["new": 阳君, "kind": 1])
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值