在项目开发中,常常会涉及到对象之间的通信,而为了降低对象间的耦合,会采用delegate、notificationCenter、block三种方式来进行实现,对于他们的使用,也许大家都能熟练掌握,但是对于如何创建,初学者也许只是一知半解,本文不讲长篇大论,仅通过简单的实例来帮助大家学习三者的使用,希望对尚不了解以上三者的朋友能带来一定的帮助。

一、delegate

  估计大家最常用的delegate就是UITableViewDelegate了,那么我们如何自己写一个代理呢?我们常常会在控制器中监听某个视图中按钮的点击,就以此为例。假如在DTestView中有一个Button,我们要在DTestViewController中对这个按钮的点击进行监听,并在点击Button时传递一个数组给DTestViewController,那么代码如下:

  1. //1、在DTestView.h文件中声明协议并创建协议方法
  2. @class DTestView;
  3. @protocol DTestViewDelegate <NSObject>
  4. @optional
  5. /**点击按钮并传递数组信息*/
  6. - (void)dTestViewDidClickBtn:(DTestView*)dTestView withArr:(NSArray *)position;
  7. @end
  8.  
  9. //2、在DTestView.h文件中声明delegate属性@interface DTestView : UIView@property (nonatomic, weak) id <DTestViewDelegate> delegate;
  10. @end
  11.  
  12. //3、在DTestView.m文件中Button的点击事件里调用delegate的协议方法
  13. - (void)btnClick {
  14. if ([self.delegate respondsToSelector:@selector(dTestViewDidClickBtn:withArr:)]) {
  15. NSArray *arr = @["test", "delegate"];
  16. [self.delegate dTestViewDidClickBtn:self withArr:arr];
  17. }
  18. }

  创建代理总共就3步,怎么样,是不是很简单?但是这之中也有几个需要注意的地方:

  1、命名规范:类名+Delegate。

  2、@optional关键字:遵循协议后,该协议方法可以不实现,协议方法默认为@required修饰,即遵循协议后必须实现该方法,建议不是必须实现的方法都用@optional修饰。

  3、ARC环境下,delegate属性用weak修饰。

  4、在调用代理方法前,利用respondsToSelector:方法判断代理方法是否存在。

  以上就是创建delegate时的注意事项,大家可以思考下为什么要这么做,如有不明白的地方,欢迎提问,如有不对的地方,欢迎指正。

  接下来就是delegate的使用了,简单说下,也是3步:

  1. //1、设置代理
  2. - (void)viewDidLoad {
  3. [super viewDidLoad];
  4. dTestView *view = [[dTestView alloc] init];
  5. view.delegate = self;
  6. [self.view addSubview:view];
  7. }
  8.  
  9. //2、遵循协议
  10. @interface DTestViewController ()<DTestViewDelegate>
  11.  
  12. //3、实现协议方法
  13. - (void)dTestViewDidClickBtn:(DtestView *)dTestView withArr:(NSArray *)arr {
  14. NSLog(@"%@", arr);
  15. }

  好了,这就是一个简单的delegate的创建与使用。

二、notificationCenter

  通知中心相对简单,仍以监听按钮点击并传递一个数组为例,在NTestView中发布通知:

  1. //在Button的addTarget点击事件中发布通知
  2. - (void)btnClick {
  3. NSArray *arr = @[@"test", @"notificationCenter"];
  4. [[NSNotificationCenter defaultCenter] postNotificationName:@"点击按钮" object:nil userInfo:arr];
  5. }

  完了?完了,就这么简单,接下来在NTestViewController中添加观察者:

  1. //添加观察者
  2. - (void)viewDidLoad {
  3. [super viewDidLoad];
  4. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nTestViewDidClickBtn:) name:@"点击按钮" object:nil];
  5. }
  6. /**接收到通知时调用该方法*/
  7. - (void)nTestViewDidClickBtn:(NSNotification *)note {
  8. NSArray *arr = note.userInfo;
  9. NSLog(@"%@", arr);
  10. }
  11.  
  12. //移除观察者
  13. - (void)dealloc
  14. {
  15. [[NSNotificationCenter defaultCenter] removeObserver:self];
  16. }

  解释一下参数:

  name:通知的名称

  object:需要传递的对象

  userInfo:发布通知是传递的信息(添加观察者时,默认可以接收该参数)

  以上,就是notificationCenter的简单使用。注意:在不需要监听时,一定要移除观察者

三、block(闭包)

  block的简单使用,仍以监听按钮点击并传递一个数组为例:

  1. //1、在BtestView.h文件中,我们可以提供这样一个类方法用于初始化:
  2. @interface BTestView : UIView
  3. /**block属性*/
  4. @property(nonatomic,copy) void(^arrBlock)(NSArray *);
  5.  
  6. /**初始化方法*/
  7. + (instancetype)bTestViewWithArrBlock:(void(^)(NSArray *arr))arrBlock;
  8. @end
  9.  
  10. //2、在BTestView.m文件中,实现该方法:
  11. + (instancetype)bTestViewWithaArrBlock:(void(^)(NSArray *arr))arrBlock {
  12. BTestView *view = [[BTestView alloc] init];
  13. _arrBlock = arrBlock;
  14. return view;
  15. }
  16.  
  17. //3、在Button的addTarge点击事件中调用arrBlock
  18. - (void)clickBtn {
  19.   NSArray *arr = @[@"test", @"notificationCenter"];
  20.   _arrBlock(arr);
  21. }

  在NTestViewController中使用block:

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. BTestView *view = [BTestView bTestViewWithArrBlock:^(NSArray *arr){
  4.     NSLog(@"%@", arr);
  5.   }];
  6.   [self.view addSubview:view];
  7. }

  不知道大家看到block用法的时候有没有一种熟悉感?

  注意:block属性要用copy修饰,同时,在使用的时候要注意不要造成循环引用。

  至于这三种通信方式具体要用哪一种?这必须结合实际项目才能做出选择,常见的一种说法是:一对多通信用notificationCenter,一对一通信在方法少的情况用block,方法多的情况用delegate。

  注意:以上代码均未通过实际测试,本文仅提供简单的使用思路。

iOS分享 - 对象间的通信之delegate、notificationCenter与block的更多相关文章

  1. NSNotification,NSNotificationCenter的使用、iOS中五种对象间传值的方式

    学习内容 NSNitification与NotificationCenter(通知与通知中心) 通知的使用 [[NSNotificationCenter defaultCenter]addObserv ...

  2. ios delegate 代理模式 观察者模式 不同视图间的通信

    delegate,在ios中比比皆是,NSURLConnection(网络请求有),tableView, connectionView,等系统自带 的常见代理.甚至,自己写代码的时候,随意间敲打出了p ...

  3. iOS开发多线程篇—线程间的通信

    iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...

  4. iOS边练边学--多线程NSOperation介绍,子类实现多线程的介绍(任务和队列),队列的取消、暂停(挂起)和恢复,操作依赖与线程间的通信

    一.NSOperation NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加 ...

  5. iOS开发多线程篇 04 —线程间的通信

    iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...

  6. C++对象间通信组件,让C++对象“无障碍交流”

    介绍 这是很久之前的一个项目了,最近刚好有些时间,就来总结一下吧! 推荐初步熟悉项目后阅读本文: https://gitee.com/smalldyy/easy-msg-cpp 从何而来 这要从我从事 ...

  7. 如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现

    姚冬,中老年程序员 叶韵.KY Xu.赵奋强 等人赞同 被邀请了很久了,一直在思考,今天终于下决心开始写回答. 这个问题的确是够大的,Qt的代码规模在整个开源世界里也是名列前茅的,这么大的项目其中的精 ...

  8. 【转】Java学习:Java中的线程之线程间的通信

    hello各位小伙伴 今天我们来搞一下 线程之间的通信 ( • ̀ω•́ )✧ 让线程按照我们的想法来执行 两个线程间的通信 这是我们之前的线程. 执行效果:谁抢到资源,谁运行~ 实现线程交替执行: ...

  9. js 页面间的通信

    看了一下公司原来的代码,原页面ajax post返回一个页面完整的HTML,然后再打开一个新页面并输出ajax返回的所有代码到新页面上,在新页面上以表单提交的形式实现重定向. 任凭我想了半天也没想出来 ...

随机推荐

  1. java学习笔记(13) —— google GSON 实现json转化方法

    1.配置struts.xml <action name="getGsonAction" class="com.test.action.json.GetGsonAct ...

  2. html5之web worker

    Web Worker   在本文中 与 Web Worker 进行双向通信 WindowTimers 在 IE10 Platform Preview 4 中对 Web Worker 的更新 API 参 ...

  3. C#实现打印与打印预览功能(转)

    在windows应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .Net Framework的打印功能都以组件的方式提供,为程序员提供了很大的方便,但是这 ...

  4. [资料] Apache2 的 httpd.conf 经典中文翻译

    [i=s] 本帖最后由 www.PHP888.com 于 2009-5-22 13:40 编辑 [/i] # 基于 NCSA 服务的配置文件. # #这是Apache服务器主要配置文件. #它包含服务 ...

  5. The given object has a null identifier解决之法

    <input type="hidden" name="memberPermission.id"            value="${memb ...

  6. Android 自定义回调

    刚开始接触的时候,觉得 回调 是一个很难理解的概念,之后就不停的上网查找回调的定义:(当你想要把具体的操作,让具体的人来完成,自己定义一个接口就好.使用的时候用接口,具体的人来实现你的接口,也就是实现 ...

  7. Altium Designer打印设置

    1:1打印PCB设置 如图1所示,打开PCB,点击“FileàPage Setup…”. 进入设置对话框,在“ScalingàScale Mode”下拉条中选择 “Scale Print”. 如图3所 ...

  8. COJ 0024 N皇后问题

    N皇后问题 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述     在N*N的方格棋盘放置N个皇,使得它们不相互攻击(即任意2个 ...

  9. iOS 9之3D Touch

    金田 北京时间9月10日凌晨, Apple在美国旧金山比尔格拉汉姆公民大礼堂(Bill Graham Civic Auditorium)召开新品发布会.本次着重介绍了3D Touch功能, 大体介绍一 ...

  10. MongoVUE简单操作手册

    本文转自网络,对疑问的地方做了修改 官方参考文献:http://www.mongovue.com/tutorials/ MongoVUE 是个比较好用的MongoDB客户端,需要注册,但是可以变成永久 ...