最近老翁在项目中多处用到了KVO,深感这种模式的好处。现总结如下:

一、概述

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

KVO其实也是“观察者”设计模式的一种应用。我的看法是,这种模式有利于两个类间的解耦合,尤其是对于 业务逻辑与视图控制 这两个功能的解耦合。

二、引子

先来看个引子:

有一个业务类:Walker,在这个类内部只负责关于业务逻辑的处理,比如负责从服务器传来的JSON中解析数据,或做其他业务数据上的处理。

有另一个类:ViewController,专门负责界面的交互与试图更新。其中,需要讲Walker的某些属性显示出来,并实时更新。

目前,据我所能想到的方法有以下几种:

方法1、直接的函数调用

Walker的类内部,把创建一个ViewController的对象,然后调用ViewController的修改界面的方法,把需要改动的属性值作为形参传给该函数。

这种方式最直观,因为它不需要绕任何弯子。但是,确实最糟的方法。因为Walker与ViewController这两个类从此紧紧耦合在一起了。记住这句话,处理业务逻辑的类,对外部的事情知道得越少越好。甚至于,要做到外部是否有VC(View Controller),有多少个VC都不影响我。假设这是一个项目,程序员A负责业务逻辑的处理,程序员B负责UI,则采取这种方式后,程序员A就受制于B,互相干扰。

方法2、利用消息通信机制(NSNotification)

在Walker内部建立消息中心NSNotificationCenter,把实例化之后的VC对象作为observer。Center建在Walker或者VC都无所谓,具体看我博客的另一篇文章【NSNotificationCenter总结】。这种方法比前面的方法好一些。但是有一个很大的缺点:如果Walker需要更改的属性很多而且很频繁,那么这种方式很不方便传值。而且,注意到了没,“把实例化后的VC对象作为observer”,始终逃不开在Walker内部对VC实例化。依旧是耦合着。

方法3、利用delegate

关于delegate的介绍有很多,这里就不多讲。但是在这种需求下用 delegate,有点“杀鸡用牛刀”感觉,成本较大,而且不直观。

方法4、利用KVO模式

所有的代码都将在ViewController中实现。对于Walker,它自己都不知道外部是否有VC,以及VC会怎用用我的属性。

三、Demo

 //
// Walker.h
// KVOExample
//
// Created by 老翁 on 13-7-29.
// Copyright (c) 2013年 wzl. All rights reserved.
// #import <Foundation/Foundation.h> @interface Walker : NSObject
{
NSInteger _age;
NSString *_name;
} @property (nonatomic) NSInteger age;
@property (nonatomic, retain) NSString *name; - (id)initWithName:(NSString *)name age:(NSInteger)age; @end
#import "Walker.h"

@implementation Walker

@synthesize age = _age;
@synthesize name = _name; - (void)dealloc
{
[_name release];
[super dealloc];
} - (id)initWithName:(NSString *)name age:(NSInteger)age
{
if (self = [super init]) {
_name = name;
_age = age;
}
return self;
} @end

ViewController代码:

//
// ViewController.h
// KVOExample
//
// Created by 老翁 on 13-7-29.
// Copyright (c) 2013年 wzl. All rights reserved.
// #import <UIKit/UIKit.h>
#import "Walker.h" @class Walker; @interface ViewController : UIViewController
{
Walker *_walker;
UILabel *_ageLabel;
} @property (nonatomic, assign) Walker *walker; @end
 //
// ViewController.m
// KVOExample
//
// Created by 老翁 on 13-7-29.
// Copyright (c) 2013年 wzl. All rights reserved.
// #import "ViewController.h" @interface ViewController () @end @implementation ViewController @synthesize walker = _walker; - (void)dealloc
{
[_walker release];
[_ageLabel release];
[super dealloc];
} - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_walker = [[Walker alloc] initWithName:@"老翁" age:];
/* 关键步骤 */
[_walker addObserver:self
forKeyPath:@"age"
options:NSKeyValueObservingOptionNew
context:nil]; //UI initialization
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(, , , )];
[btn setBackgroundColor:[UIColor lightGrayColor]];
[btn setTitle:@"增加5岁" forState:UIControlStateNormal];
[btn addTarget:self
action:@selector(buttonPressed)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn]; _ageLabel = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
_ageLabel.text = [NSString stringWithFormat:@"%@现在的年龄是: %d", _walker.name, _walker.age];
_ageLabel.backgroundColor = [UIColor clearColor];
[self.view addSubview:_ageLabel]; } - (void)buttonPressed
{
_walker.age += ;
} /* KVO function, 只要object的keyPath属性发生变化,就会调用此函数*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"age"] && object == _walker) {
_ageLabel.text = [NSString stringWithFormat:@"%@现在的年龄是: %d", _walker.name, _walker.age];
}
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end

点击了按钮之后,系统会调用 observeValueForKeyPath :函数,这个函数应该也是回调函数。在该函数内部做UI更新。我们以这种轻量级的方式达到了目的。

##################################################

声明 转载请注明原文地址:

http://www.cnblogs.com/wengzilin/p/3223770.html

欢迎私下交流学习:

QQ 719113951

##################################################

【原】IOS中KVO模式的解析与应用的更多相关文章

  1. IOS中KVO模式的解析与应用

    IOS中KVO模式的解析与应用 最近老翁在项目中多处用到了KVO,深感这种模式的好处.现总结如下: 一.概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修 ...

  2. js中State模式的解析及运用

     状态模式,在大的范畴中的定义为当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类.每种编程语言有不同的实现方式,运用的范围也多用于游戏之中. 这里我用javascript来模拟状 ...

  3. iOS 中架构模式的浅显理解

    我们开发软件中应用各种模式,主要是为了 职责划分:一个类只做一件事 易用,可维护,方便扩展 解耦,相互独立,可单独测试 各种设计模式其实都是在解决上面的问题,让我们对比看看吧. 一.如何理解MVC设计 ...

  4. [原]iOS中 Web 页面与 Native Code 的一种通信方式

    在 iOS 开发中,Web 页面与 Native Code 通信可以分为两个方面: 1.Native Code 调用 Web 页面的方法:主要是调用页面中的 Javascript 函数. 2.Web ...

  5. iOS中UITextField 使用全面解析

    //初始化textfield并设置位置及大小   UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...

  6. iOS中UITextField 使用全面解析 分类: ios技术 2015-04-10 14:37 153人阅读 评论(0) 收藏

    //初始化textfield并设置位置及大小   UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...

  7. iOS中 KVO 键值观察者

    KVO Key-Value-Obsever 键值观察者 1.首先要有一个观察者,此时被观察者是自己找一个观察者观察自己的key值对应的value值有没有改变,如果改变了就可以做一些响应的操作 创建一个 ...

  8. iOS边练边学--iOS中的XML数据解析

    XML的解析方式 SAX 大小文件都可以 NSXMLParser DOM 最好是小文件 GDataXML NSXMLParser的用法 创建解析器来解析 // 创建XML解析器 NSXMLParser ...

  9. iOS边练边学--iOS中的json数据解析

    JSON数据(NSData) -> OC对照表 {} -> NSDictionary @{} [] -> NSArray @[] "jack" -> NSS ...

随机推荐

  1. Flex Error #2156问题

    出现这个问题是因为应用程序使用了特殊端口,修改端口就可以解决. 特殊端口列表 A security change has been made in Adobe Flash Player 9.0.115 ...

  2. 表格CSS样式美化

    1. 单像素边框CSS表格 这是一个很常用的表格样式. <!-- CSS goes in the document HEAD or added to your external styleshe ...

  3. ios auto layout demystified (二)

    Constraints Constraint Types Layout constraints (NSLayoutConstraint class, public)—这些规则指定了view的几何学.他 ...

  4. maven pox.xml 设置主入口配置节点

    <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...

  5. rabbitmq使用dead letter机制来进行retry

    首先建立 工作exchange和工作queue,指定工作队列的x-dead-letter-exchange到重试exchenge var workQueueArgs = new Dictionary& ...

  6. java io系列01之 "目录"

    java io 系列目录如下: 01. java io系列01之  "目录" 02. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括 ...

  7. UML系列01之 UML和绘图工具Visio介绍

    概要 UML,全称是Unified Modeling Language,中文是"统一建模语言".通俗点说,UML是一种创建模型的语言.UML是在开发阶段,说明,可视化,构建和书写一 ...

  8. [IR] Index Construction

    Three steps to construct Inverted Index as following: 最难的step中: Token sequence. Sort by term. Dictio ...

  9. 想从事分布式系统,计算,hadoop等方面,需要哪些基础,推荐哪些书籍?--转自知乎

    作者:廖君链接:https://www.zhihu.com/question/19868791/answer/88873783来源:知乎 分布式系统(Distributed System)资料 < ...

  10. sublime text3 安装package

    在sublime text2中安装package control插件的时候是执行python: import urllib2,os; pf='Package Control.sublime-packa ...