在实际开发中我们经常遇到需要跨方法,甚至跨文件访问数据或传输信息,跨方法是比较简单的,只要我们声明一个全局变量,并为其赋值,就可以在同一个文件中的任意位置调用了。而跨文件传输数据,就要相对麻烦一点了,开发中常用的方法有代理、通知和block,下面我们将逐一介绍。
为了介绍这三种方法,我们写一个小Demo,对这三种方法进行说明。界面比较简单,搭界面我们就不在这里展示了,主要展示数据传递的方法,思路是点击相应按钮,把各自文件中的数据传过来,显示在上面的label。
一、代理
代理的使用,可以简单的概括为两个三步走,即创建代理的三步和使用代理的三步。
创建代理:
* 创建代理协议
* 声明代理方法
* 声明代理属性
使用代理:
* 遵守代理协议
* 设置代理对象
* 实现代理方法
下面我们直接上代码,实现点击代理按钮,上面的label显示“这是代理传的值”
#import <UIKit/UIKit.h> @class Demo; //创建代理协议 @protocol DemoDelegate <NSObject> //声明代理方法 @optional - (void)demoName:(NSString *)name; @end @interface Demo : UIView //声明代理属性 @property (nonatomic, weak) id<DemoDelegate> delegate; @end
/* 调用代理方法 */ - (void)deleBtnClick{ //要传递的对象 NSString *myText = @"这是代理传的值"; if ([self.delegate respondsToSelector:@selector(demoName:)]) { [self.delegate demoName:myText]; } }
/* 实现代理方法 */ -(void)demoName:(NSString *)name{ self.myLabel.text = name; }
代理回调是这三种方法中最简单最直接的,一对一传值是代理传值最显著的特点。
二、通知
每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的信息通信。
任何一个对象都可以向通知中心发布通知(NSNotification),描述自己在做什么。其他感兴趣的对象(Observer)可以申请在特定通知发布时(或在某个特定的对象发布通知时)收到这个通知。
通知和代理最大的不同就是,通知可以实现一对多传值。代理实现可以分为以下几步:
* 创建发布通知的对象和接收通知的对象
* 创建通知
* 获取通知中心
* 注册监听者
* 发布通知
* 销毁监听对象
这是一个完整的监听的实现,在使用过程中某些步骤可以省略合并,监听的实现如下图所示:
下面就上代码了
/* 发布通知 */ - (void)notyBtnClick{ //要传递的对象 NSString *myText = @"这是通知传的值"; [[NSNotificationCenter defaultCenter] postNotificationName:kMyNotyName object:myText]; }
/* 注册监听 */ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noty:) name:kMyNotyName object:nil];
/* 接收通知 */ - (void)noty:(NSNotification *)noty{ self.myLabel.text = noty.object; }
- (void)dealloc{ // 移除通知 [[NSNotificationCenter defaultCenter] removeObserver:self]; }
二、Block
这里有必要对Block的结构做一个简单的梳理
Black对象是一个c语言级别的语法和运行机制。它与标准c函数类似,不同之处在于,它除了有可执行的代码之外,还包含了与堆、栈内存绑定的变量。作为一个回调,Block特别的有用,因为block既包含了回调期间的代码,又包含了执行期间需要的数据。一个标准的block声明如下:
int (^myBlock)(init)=^(int num){return num *multiplier;};
下面就用代码说明Block传值
//声明块,这个块的返回值类型为void,参数类型为Nsstring,形参名为myText @interface Demo : UIView @property (nonatomic, copy) void (^myBlock)(NSString *myText); @end
-(void)blockBtnClick{ //要传递的对象 NSString *myText = @"这是block传的值"; if (self.myBlock) { self.myBlock(myText); } }
myView.myBlock = ^(NSString *myText){ weakSelf.myLabel.text = myText; };