对象间的通信之delegate、notificationCenter与block

2024-06-16 20:38

本文主要是介绍对象间的通信之delegate、notificationCenter与block,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

一、delegate

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

//1、在DTestView.h文件中声明协议并创建协议方法
@class DTestView;
@protocol DTestViewDelegate <NSObject>
@optional
/**点击按钮并传递数组信息*/
- (void)dTestViewDidClickBtn:(DTestView*)dTestView withArr:(NSArray *)position;
@end//2、在DTestView.h文件中声明delegate属性
@interface DTestView : UIView
@property (nonatomic, weak) id <DTestViewDelegate> delegate;
@end//3、在DTestView.m文件中Button的点击事件里调用delegate的协议方法
- (void)btnClick {if ([self.delegate respondsToSelector:@selector(dTestViewDidClickBtn:withArr:)]) {NSArray *arr = @["test", "delegate"];[self.delegate dTestViewDidClickBtn:self withArr:arr];}         
}
创建代理总共就3步,怎么样,是不是很简单?但是这之中也有几个需要注意的地方:
1、命名规范:类名+Delegate。
2、@optional关键字:遵循协议后,该协议方法可以不实现,协议方法默认为@required修饰,即遵循协议后必须实现该方法,建议不是必须实现的方法都用@optional修饰。
3、ARC环境下,delegate属性用weak修饰。
4、在调用代理方法前,利用respondsToSelector:方法判断代理方法是否存在。

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

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

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

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

二、notificationCenter

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

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

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

//添加观察者
- (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nTestViewDidClickBtn:) name:@"点击按钮" object:nil];
}
/**接收到通知时调用该方法*/
- (void)nTestViewDidClickBtn:(NSNotification *)note {NSArray *arr = note.userInfo;NSLog(@"%@", arr);
}//移除观察者
- (void)dealloc
{[[NSNotificationCenter defaultCenter] removeObserver:self];
}

解释一下参数:

name:通知的名称

object:需要传递的对象

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

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

三、block(闭包)

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

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

在NTestViewController中使用block:

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

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

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

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

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

这篇关于对象间的通信之delegate、notificationCenter与block的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067493

相关文章

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

Java如何通过反射机制获取数据类对象的属性及方法

《Java如何通过反射机制获取数据类对象的属性及方法》文章介绍了如何使用Java反射机制获取类对象的所有属性及其对应的get、set方法,以及如何通过反射机制实现类对象的实例化,感兴趣的朋友跟随小编一... 目录一、通过反射机制获取类对象的所有属性以及相应的get、set方法1.遍历类对象的所有属性2.获取

java中VO PO DTO POJO BO DO对象的应用场景及使用方式

《java中VOPODTOPOJOBODO对象的应用场景及使用方式》文章介绍了Java开发中常用的几种对象类型及其应用场景,包括VO、PO、DTO、POJO、BO和DO等,并通过示例说明了它... 目录Java中VO PO DTO POJO BO DO对象的应用VO (View Object) - 视图对象

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

Java将时间戳转换为Date对象的方法小结

《Java将时间戳转换为Date对象的方法小结》在Java编程中,处理日期和时间是一个常见需求,特别是在处理网络通信或者数据库操作时,本文主要为大家整理了Java中将时间戳转换为Date对象的方法... 目录1. 理解时间戳2. Date 类的构造函数3. 转换示例4. 处理可能的异常5. 考虑时区问题6.

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(