一、Delegate

Delegate本质是一种程序设计模型,iOS中使用Delegate主要用于两个页面之间的数据传递。iphone中常用@protocol和delegate的机制来实现接口的功能。例如想在A的功能要在B中实现,可以在A中定义一个Protocol。

protocol用法:
@interface ClassA :ClassB<protocol1, protocol2>
1、首先声明一个UIView类:
@interface myView  :UIView{  }
@end;

2、声明一个protocol,前缀为protocol :

@protocol myViewDelegate

-(void) Fun1;

-(void) Fun2;
@end;
3、之后就是代理委托人,委托的声明方式如下,我们要在ClassB内使用Fun1方法,但是不需要做声明:
@interface ClassB :UIViewController<myViewDelegate>
@end
4、ClassB实现:
@implement ClassB
 -init{
        MyView *view = [[MyView alloc]init];
        view.delegate = self;
        self.view = view;
       }
-(void)Fun1{
       }
@end
如果要在ClassA中使用Fun1,需要在ClassA的声明中添加:
@interface myView  :UIView{
id<myViewDelegate> delegate;
}
@property ...
@end

具体实现中时:

-(void)action{

  [delegate Fun1];
}
二、NSNotification

NSNotification是用来在类之间传递消息参数的。每个运行中的application都有一个NSNotificationCenter的成员变量,它的功能就类似公共栏。

对象注册关注某个确定的notification(比如说老师通知今天上午课取消). 我们把这些注册对象叫做 observer. 其它的一些对象会给center发送notifications(今天上午课取消). center将该notifications转发给所有注册对该notification感兴趣的对象. 我们把这些发送notification的对象叫做 poster。

具体使用方法有四个步骤:

1、定义一个事件到来时该执行的方法

 - (void)stopClass:(NSNotification*)notification{

 //今天不上课

 }

2、注册观察者

参数介绍:

addObserver: 观察者,即在什么地方接收通知;

selector: 收到通知后调用何种方法;

name: 通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的;

object:传递的参数

     [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(stopClass:)
                                                  name:@"NotoficationName"
                                                object:nil];

3、激发事件,即通知相应的观察者

 [[NSNotificationCenter defaultCenter] postNotificationName:@"NotoficationName"
                                                         object:nil];

代码到这里,- (void)stopClass:(NSNotification*)notification方法就会执行了;事件只会在当前的 NotificationCenter 中广播,不同的 NotificationCenter 之间的事件通知互不相干(就像上面的例子,今天上午课取消只是针对我班,不影响别班)

4、移除通知;(最后,你的观察者如果对一些事件没兴趣了,应该从 NotificationCenter 中移除掉)

 //与注册时相同
     [[NSNotificationCenter defaultCenter] removeObserver:self
                                                     name:@"NotoficationName"
                                                   object:nil];
     //或者
     [[NSNotificationCenter defaultCenter] removeObserver:self];

三、KVO

KVO,全称为Key-Value Observing,是iOS中的一种设计模式。用于检测对象的某些属性的实时变化情况并作出响应,即当指定的对象的属性被修改后,则对象就会接受到通知,简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。与NSNotification相比之下KVO更加简洁而直接。

KVO的使用也很简单,就是简单的3步:
      1.注册需要观察的对象的属性addObserver:forKeyPath:options:context:
      2.实现observeValueForKeyPath:ofObject:change:context:方法,这个方法当观察的属性变化时会自动调用
      3.取消注册观察removeObserver:forKeyPath:context:

实例:假设我在双十一之前看中一件衣服,双十一衣服价格会有变动,我需要监听衣服的价格变动。

1、定义一个Model

 @interface DataModel:NSObject (){
     DataModel *shirtForKVO;
     UILabel *myLabel;
     UIButton *myButton;

     NSString *shirt;
     float price;

 }

2、实例化

 - (void)viewDidLoad {

     shirtForKVO = [[DataModel alloc] init];
     [shirtForKVO setValue:@"myShirt" forKey:@"shirt"];
     [shirtForKVO setValue:@"150.0" forKey:@"price"];
     [shirtForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

     myLabel = [[UILabel alloc] initWithFrame:(CGRect){,,,}];
     myLabel.text = [shirtForKVO valueForKey:@"price"];
     myLabel.textColor = [UIColor orangeColor];
     [self.view addSubview:myLabel];

     myButton = [[UIButton alloc] initWithFrame:(CGRect){,,,}];
     myButton.backgroundColor = [UIColor purpleColor];
     [myButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
     [self.view addSubview:myButton];

 }

3、当点击button的时候,调用buttonAction方法,修改对象的属性

 - (void)buttonAction{

     [shirtForKVO setValue:@"100.0" forKey:@"price"];

 }

4、实现回调方法

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

     if ([keyPath isEqualToString:@"price"]) {
         myLabel.text = [shirtForKVO valueForKey:@"price"];
     }

 }

5、移除观察者

 - (void)dealloc{

     [shirtForKVO removeObserver:self forKeyPath:@"price"];

 }

四、Delegate 、NSNotification 、KVO之间的联系及其区别

区别:

delegate方法往往需要关注返回值, 也就是delegate方法的结果。

delegate只是一对一,而NSNotification、KVO可以一对多,两者都没有返回值。

各自特点:

NSNotification的特点,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但是其优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活。

KVO只能检测类中的属性,并且属性名都是通过NSString来查找,编译器不会帮你检错和补全,所以比较容易出错。

delegate方法最典型的特征是往往需要关注返回值。

ios基础篇(十八)——Delegate 、NSNotification 和 KVO用法及其区别的更多相关文章

  1. ios基础篇(八)——UITabBarController的简单介绍

    一.简介 UITabBarController和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型的例子就 ...

  2. WF4.0 基础篇 (十八) Flowchar

    本节主要介绍WF4 中 Flowchart的使用 本文例子下载: http://files.cnblogs.com/foundation/FlowcharSample.rar 本文例子说明 Flowc ...

  3. ios基础篇(二)——UIImageView的常见用法

    UIImageView是在界面上显示图片的一个控件,在UIImageView中显示图片的话应该首先把图片加载到UIImage中,然后通过其他方式使用该UIImage. 创建UIImageView有两种 ...

  4. Bootstrap &lt;基础二十八&gt;列表组

    列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...

  5. Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

    写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...

  6. Java多线程系列--“基础篇”03之 Thread中start()和run()的区别

    概要 Thread类包含start()和run()方法,它们的区别是什么?本章将对此作出解答.本章内容包括:start() 和 run()的区别说明start() 和 run()的区别示例start( ...

  7. ios基础篇(二十八)—— UITableView的上拉加载

    本文主要展示一个demo实现UITableView的上拉加载数据: 先看看效果图: 接着上拉,加载更多数据: 主要实现的效果是在我们上拉结束拖拽之后,开始加载数据,数据加载的过程中有滚动轮提示用户正在 ...

  8. ios基础篇(十六)——UIWebView的基本使用

    UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档等.UIWebView是一个混合体,具体的功能控件内置的,实现一些基本的功能.UIWebView可以查看Html网页,pdf文件,do ...

  9. ios基础篇(二十六)—— UITableViewCell的分组索引与标记

    一.表视图的索引目录 首先要创建一个TableView,之前有说过,这里就不详细说了(参考前面第十四篇). 直接贴代码吧, #import "ViewController.h" @ ...

随机推荐

  1. 苹果台式一体机笔记本安装win双系统攻略教程

    步骤 序:win系统下载 :http://www.itellyou.cn 选择要安装的系统进行下载,本文以win7为例   进入苹果系统,左上角——前往——实用工具——BootCamp 助理 点击继续 ...

  2. Angular内置指令(一)

    要注意的是不要把自己开发的指令以ng开头,以免与内置指令冲突  目录:ng-disabled,ng-readonly,ng-checked,ng-selected,ng-href,ng-src,ng- ...

  3. [译]Kinect for Windows SDK开发入门(十八):Kinect Interaction交互控件

    本文译自 http://dotneteers.net/blogs/vbandi/archive/2013/03/25/kinect-interactions-with-wpf-part-i-getti ...

  4. 备忘-Sql server Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置

    select * from sysprocesses where dbid= db_id('数据库名') 通过此语句可查看目前所有的连接进程 不够了就必须设置Max Pool Size,理论最大值为3 ...

  5. JSP利用Hibernate实现对数据库的CRUD ——开发环境Myeclipse与SQL Server 2008

    一.首先先建立一个Web Project 二.然后在程序根目录建立文件夹“DataBase”和“Doc”,分别存放数据库文件和保存SQL语句,建完如下所示: 三.建立数据库“dbHibernate”, ...

  6. Android之查看网络图片和网页HTML

    网络编程是Android应用中很重要的一部分,本文主要讲述了利用HttpURLConnection获取网络图片和HTML的方法. 获取网络图片 public class MainActivity ex ...

  7. 神奇的Noip模拟试题 T3 科技节 位运算

    3 科技节 (scifest.pas/.c/.cpp) [问题描述] 一年一度的科技节即将到来.同学们报名各项活动的名单交到了方克顺校长那,结果校长一看皱了眉头:这帮学生热情竟然如此高涨,每个人都报那 ...

  8. reduce的数目到底和哪些因素有关

      reduce的数目到底和哪些因素有关 1.我们知道map的数量和文件数.文件大小.块大小.以及split大小有关,而reduce的数量跟哪些因素有关呢? 设置mapred.tasktracker. ...

  9. C#连接SQLite数据库方法

    --结合Enterprise Library连接,操作SQLite 企业库是我们常用的框架之一,可以从http://entlib.codeplex.com/下载Enterprise Library 5 ...

  10. Windows下编译openssl

    依赖工具: 1.VS 2.perl 编译方法: release: :\> 切换到openssl目录 :\> perl Configure VC-WIN32 no-asm --prefix= ...