概述

键值编码(KVC)、键值监听(KVO)特性

键值监听KVO

Key Value Observing(简称KVO)其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过幸运的是NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。

在ObjC中使用KVO操作常用的方法如下:

  • 注册指定Key路径的监听器: addObserver: forKeyPath: options:  context:
  • 删除指定Key路径的监听器: removeObserver: forKeyPathremoveObserver: forKeyPath: context:
  • 回调监听: observeValueForKeyPath: ofObject: change: context:

KVO的使用步骤也比较简单:

  1. 通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
  2. 重写监听器的observeValueForKeyPath: ofObject: change: context:方法
  3. 删除指定Key路径的监听器: removeObserver: forKeyPath、removeObserver: forKeyPath: context:

例子:

1.我们新建一个账号模型

Account.h

  1. #import <Foundation/Foundation.h>
  2.  
  3. @interface Account : NSObject
  4.  
  5. /** 余额 */
  6. @property (nonatomic, assign) float balance;
  7.  
  8. @end

2.在新建一个用户模型

Person.h

  1. #import <Foundation/Foundation.h>
  2. @class Account;
  3.  
  4. @interface Person : NSObject
  5.  
  6. /** 名字 */
  7. @property (nonatomic, copy) NSString *name;
  8. /** 账号 */
  9. @property (nonatomic, retain) Account *account;
  10.  
  11. @end

3.在Person.m Model里使用

  1. //
  2.  
  3. #import "Person.h"
  4. #import "Account.h"
  5.  
  6. @implementation Person
  7.  
  8. - (void)setAccount:(Account *)account
  9. {
  10. _account = account;
  11. [self.account addObserver:self forKeyPath:@"balance" options:NSKeyValueObservingOptionNew context:nil];
  12. }
  13.  
  14. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
  15. if ([keyPath isEqualToString:@"balance"]) {
  16. NSLog(@"keyPath=%@,object=%@,newValue=%.2f,context=%@",keyPath,object,[[change objectForKey:@"new"] floatValue],context);
  17. }
  18. }
  19.  
  20. - (void)dealloc{
  21. [self.account removeObserver:self forKeyPath:@"balance"];// 移除监听
  22. }
  23.  
  24. @end

ViewController 就很简单了

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3.  
  4. Person *person = [[Person alloc] init];
  5. person.name = @"jiangys";
  6. _account = [[Account alloc] init];
  7. person.account = _account;
  8.  
  9. _account.balance = ; // 监听生效
  10. }

但是这种方式,是不能更新到界面的。可能使用到这种场景,比如 暂停,快进这些,不需要界面变化的好一些。如果需要界面变化,如账号余额的变化等,那就需要放在Controller里面去做UI的更新了。

  1. //
  2. // ViewController.m
  3. // KVO
  4. //
  5. // Created by jiangys on 16/4/19.
  6. // Copyright © 2016年 Jiangys. All rights reserved.
  7. //
  8.  
  9. #import "ViewController.h"
  10. #import "Person.h"
  11. #import "Account.h"
  12.  
  13. @interface ViewController ()
  14. /** 账号 */
  15. @property (nonatomic, retain) Account *account;
  16. @end
  17.  
  18. @implementation ViewController
  19.  
  20. - (void)viewDidLoad {
  21. [super viewDidLoad];
  22.  
  23. Person *person = [[Person alloc] init];
  24. person.name = @"jiangys";
  25. _account = [[Account alloc] init];
  26. person.account = _account;
  27. // 增加KVO监听
  28. [_account addObserver:self forKeyPath:@"balance" options:NSKeyValueObservingOptionNew context:nil];
  29.  
  30. _account.balance = ;
  31.  
  32. _account.balance = ;
  33. }
  34.  
  35. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
  36. if ([keyPath isEqualToString:@"balance"]) {
  37. NSLog(@"keyPath=%@,object=%@,newValue=%.2f,context=%@",keyPath,object,[[change objectForKey:@"new"] floatValue],context);
  38. }
  39. }
  40.  
  41. - (void)dealloc{
  42. [_account removeObserver:self forKeyPath:@"balance"];// 移除监听
  43. }
  44.  
  45. - (void)didReceiveMemoryWarning {
  46. [super didReceiveMemoryWarning];
  47. // Dispose of any resources that can be recreated.
  48. }
  49.  
  50. @end

KVO源代码下载:http://pan.baidu.com/s/1qYh7y8W

iOS 开发笔记-Objective-C之KVC、KVO的更多相关文章

  1. IOS开发-OC学习-kvc,kvo

    kvc是用来方便的设置实例的属性值的,比如person类的实例p1有一个name的属性,那么我们可以通过kvc去设置p1的name,语法是: [ 对象 setValue:@"xiaming& ...

  2. iOS开发技巧系列---详解KVC(我告诉你KVC的一切)

    KVC(Key-value coding)键值编码,单看这个名字可能不太好理解.其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值.而不需 ...

  3. 菜鸟手下的iOS开发笔记(swift)

    在阳春4月的一天晨会上,有一个老板和蔼的对他的一个菜鸟手下说:“你既然会Android,那你能不能开发iOS?” 不是说好的要外包的吗?内心跌宕,但是表面淡定的菜鸟手下弱弱的回道:“可以试试”. 第二 ...

  4. iOS开发笔记7:Text、UI交互细节、两个动画效果等

    Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...

  5. iOS开发笔记-两种单例模式的写法

    iOS开发笔记-两种单例模式的写法   单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h" ...

  6. iOS开发笔记--什么时候调用layoutSubviews

    iOS开发笔记--什么时候调用layoutSubviews 分类: iOS2014-04-22 16:15 610人阅读 评论(0) 收藏 举报 今天在写程序时候遇见layoutSubviews触发时 ...

  7. IOS开发笔记(4)数据离线缓存与读取

    IOS开发笔记(4)数据离线缓存与读取 分类: IOS学习2012-12-06 16:30 7082人阅读 评论(0) 收藏 举报 iosiOSIOS 方法一:一般将服务器第一次返回的数据保存在沙盒里 ...

  8. IOS开发笔记 IOS如何访问通讯录

    IOS开发笔记  IOS如何访问通讯录 其实我是反对这类的需求,你说你读我的隐私,我肯定不愿意的. 幸好ios6.0 以后给了个权限控制.当打开app的时候你可以选择拒绝. 实现方法: [plain] ...

  9. 【Swift】iOS开发笔记(二)

    前言 这个系列主要是一些开发中遇到的坑记录分享,有助于初学者跨过这些坑,攒够 7 条发一篇. 声明  欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯 ...

  10. iOS开发——OC篇&消息传递机制(KVO/NOtification/Block/代理/Target-Action)

     iOS开发中消息传递机制(KVO/NOtification/Block/代理/Target-Action)   今晚看到了一篇好的文章,所以就搬过来了,方便自己以后学习 虽然这一期的主题是关于Fou ...

随机推荐

  1. checkbox做全部选中,全部取消效果

    批量选中.取消多个checkbox的用法很简单,这个功能也很常用.这里做个总结. 在HTML中的写法: <div id="ftpFileDownTr"> <but ...

  2. 【单调栈】hdu 6319 杭电多校Problem A. Ascending Rating

    http://acm.hdu.edu.cn/showproblem.php?pid=6319 从后往前更新,维护一个递减单调栈(队列) 最近很多题都是单调栈... #define _CRT_SECUR ...

  3. shell脚本之流程控制语句

    一.分支控制语句 1.if .. fi条件 if condition; then action fi 2.if .. else .. fi条件 if condition;then action; el ...

  4. win10 SVN不能显示图标

    参考的解决办法有很多(http://blog.csdn.net/lishehe/article/details/8257545),大多数是操作一下注册表. 我就按照他们的办法,svn的注册表顺序根本上 ...

  5. C#配置.INI文件

    百度搜了一些资料,好多没给示例,只给了代码.让人看了直接懵逼,后来找了个靠谱的:http://www.jb51.net/article/118591.htm

  6. Go编写的并行计算示例程序

    Go编写的并行计算示例程序 package main import "fmt" const ngoroute = 1000000 func f(left, right chan i ...

  7. A crawler that sent a DELETE request to every resource it encountered

    RESTful Web APIs_2013 The crawler simulates a very curious but not very picky human. Give it a URL t ...

  8. 内部排序->选择排序->堆排序

    文字描述 堆排序中,待排序数据同样可以用完全二叉树表示, 完全二叉树的所有非终端结点的值均不大于(或小于)其左.右孩子结点的值.由此,若序列{k1, k2, …, kn}是堆,则堆顶元素(或完全二叉树 ...

  9. linux strncpy()和strcat使用总结

    strcat原型:char *strcat(char *dest,const char *src); 把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'.src和de ...

  10. 【Python全栈-JavaScript】JavaScript入门

    JavaScript基础知识点 一.JavaScript概述 参考:http://www.w3school.com.cn/b.asp JavaScript的历史 1.1992年Nombas开发出C-m ...