页面传值--Delegate/Block/KVO/Notification

上一篇讲了Block的页面传值。这里也就顺便把常用的几种页面传值放上来。这里我写了一个Demo:https://github.com/ChenNan-FRAM/TransferDataDemo 。想下的可以上去下载来看看。

这里主要把上一篇提到的四种方式说一下(话不多说直接核心代码讲)。
1、使用Delegate
2、使用Notification
3、使用Block
4、使用KVO

定义及使用

第二个界面.h 头文件

//定义一个委托协议
@protocol NextVCDelegate <NSObject>
- (void)tranferText: (NSString *)text;
@end

@interface NextVC : UIViewController

@property (nonatomic, assign)id<NextVCDelegate> delegate;//设置委托属性
@property (nonatomic, copy) void(^NextVCBlock)(NSString *text);//设置Block属性
@property (nonatomic, strong) UITextField *text;

- (id)init;
@end

第二个页面.m文件,以下都是按钮返回第一个页面的触发事件

#pragma mark -- 使用Block进行页面传值----------
- (void)transferUseBlock {
    if (self.NextVCBlock)
        self.NextVCBlock(_text.text);

    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark -- 使用Notification进行页面传值----------
- (void)transferUseNotice {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"tranferText" object:_text.text];
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark -- 使用KVO进行页面传值----------
- (void)transferUseKVO {
    [self setValue:_text.text forKeyPath:@"text.text"];
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark -- 使用Delegate进行页面传值----------
- (void)transferUseDelegate {

    if (self.delegate && [self.delegate respondsToSelector:@selector(transferText:)]) {
        [self.delegate transferText:_text.text];
    }

    [self.navigationController popViewControllerAnimated:YES];
}

第一个页面 .m文件,头文件无其他定义。

#pragma mark -- 使用Notification传值---------------
- (void)addNotice {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotice:) name:@"tranferText" object:nil];
}
- (void)removeNotice {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"tranferText" object:nil];
}

// @brief  按钮事件,使用notification传值
- (void)toNext_Notice {
    [self addNotice];//注册通知
    NextVC *next = [[NextVC alloc]init];
    [self.navigationController pushViewController:next animated:YES];
}
//触发
- (void)receiveNotice:(NSNotification *)notice {
    NSString *text = (NSString *)notice.object;
    _useNoticeText.text = [NSString stringWithFormat:@"I‘m from notice : %@", text];
    [self removeNotice];//移除通知
}

#pragma mark -- 使用Block传值-----------------------
//@brief  按钮事件,使用block传值,包括触发
- (void)toNext_Block {

    NextVC *next = [[NextVC alloc]init];

    __weak typeof (NextVC) *weakNext = next;

    weakNext.NextVCBlock = ^(NSString *text){
        _useBlockText.text = [NSString stringWithFormat:@"I‘m from block : %@", text];
    };

    [self.navigationController pushViewController:next animated:YES];
}

#pragma mark -- 使用KVO传值-----------------
// @brief  按钮事件,使用KVO传值
- (void)toNext_KVO {

    NextVC* next = [[NextVC alloc]init];
    [next addObserver:self forKeyPath:@"text.text" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

    [self.navigationController pushViewController:next animated:YES];
}

//触发
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    NextVC *next = (NextVC *)object;
    if ([keyPath isEqualToString:@"text.text"]) {
        _useKVOText.text = [NSString stringWithFormat:@"I‘m from KVO : %@",next.text.text];
    }

    [next removeObserver:self forKeyPath:@"text.text" context:nil];
}

#pragma mark -- 使用Delegate传值----------------
//@brief  按钮事件,使用delegate传值
- (void)toNext_Delegate {

    NextVC *next = [[NextVC alloc]init];
    next.delegate = self;
    [self.navigationController pushViewController:next animated:YES];
}

//触发
#pragma mark - NextVCDelegate
- (void)transferText:(NSString *)text {
    _useDelegateText.text = [NSString stringWithFormat:@"I‘m from delegate : %@", text];
}

思路

  • Delegate:定义一个协议,然后到需要触发的地方传输数据并委托另一个页面去实现。如果只需要简单传值就比较繁复。 但需要一个页面触发多个事件的话还是一个很好的机制。
  • Block:通过在第一个页面调用第二个页面持有的block属性并获得block的内部参数。而且比较简单方便,推荐使用。在UIKit的动画中也是频繁使用的,功能很强大也尚在挖掘中,具体了解可看我上两篇博文对block的介绍。Block的注意点我也在上一篇博文中有提到:传送链接
  • Notification:需要在第一个页面注册一个通知,然后第二个页面需要触发第一个页面的事件时就给通知中心发送一个通知,这个通知是公开的,也就是相当于一个公告栏,但只有注册了该通知的控制器才会触发该事件。但是如果是过于频繁的向通知中心发送某一些通知就比较不适用了。
  • KVO:KVO也是个很好的机制。虽然跟Notification一样采用的也是观察者模式,不过KVO在一对一方面用的是比较多的,虽然也可以一对多。但建议一对一。但我们需要知道我们要观察对象的键路径。这里还有另外一个提示点,我们在一个方法中新建一个被观察对象并为它注册观察者,当这个方法调用结束的时候这个被观察对象会被释放,但注册的观察关系没有被解除,这会导致crash。所以在观察事件结束后要记得remove掉观察关系。

至于NSUserDefault等文件存储介质这些涉及到磁盘文件等的可能会新开一个博文做总体介绍。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-10 07:47:22

页面传值--Delegate/Block/KVO/Notification的相关文章

页面传值总结Block

// // AppDelegate.m // 页面传值总结 // // Created by qianfeng on 15/6/13. // Copyright (c) 2015年 qianfeng. All rights reserved. // #import "AppDelegate.h" #import "ViewController.h" @interface AppDelegate () @end @implementation AppDelegate

iOS页面传值之Block传值

场景A控制器中有一个Label  B控制器中有一个文本输入框textField A push 到B 当,B返回A时,我们让B中文本框的内容展示到A中去 第一步: 在B中定义Block #import <UIKit/UIKit.h> typedef void(^PassValueOption)(NSString*); @interface ZPViewControllerB : UIViewController @property(nonatomic,copy)PassValueOption o

Block的使用--页面传值方法及探究

上一篇讲了Block的简单实用,这一篇则是讲述Block的最经常也是比较简单的用法,个人认为这是block相对其他页面传值方式比较好的一个用处.也顺便总结下这两天对Block的理解的一些注意点. 对于页面传值这种情况,我们一般在程序里有几种处理的方法. 1.设置Delegate 2.使用NotificationCenter 3.使用Block 4.KVO页面传值 5.NSUserDefault等文件存储机制做中间介质传递(但比较浪费,用在页面传值上几率很低) 这一篇博客我只讲一下Block的一般

block 页面传值小结

我以自己项目中的一个模块为例,首先有两个页面,第一个页面为显示城市页面,第二个页面为选择要使用block传的值(城市名). 第一个页面中的显示控件: //自定义左部定位视图 self.locView = [[LocationView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH/2-35, 25)]; self.locView.imgView.image = [UIImage imageNamed:@"around"]; UITap

KVC,KVO,Notification,delegate

iOS 中KVC.KVO.NSNotification.delegate 总结及区别 1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的关键技术之一. Demo: @interface myPerson : NSObject { NSString*_name; int      _age; int      _height; int      _w

IOS 委托代理(delegate)实现页面传值

LvesLi原创,转载请注明原文链接谢谢  http://www.androiddev.net/lvesli_delegate/  委托是指给一个对象提供机会对另一对象中的变化做出反应或者相应另一个对象的行为.其基本思想是协同解决问题. 在程序中:一般情况下 1.委托需要做的工作有: 1.1定义协议与方法 1.2声明委托变量 1.3设置代理 1.4通过委托变量调用委托方法 2.代理需要做的工作有: 2.1遵循协议 2.2实现委托方法 下面讲解一下使用委托实现页面传值的解决方法: 加入我们有两个V

ios常见的页面传值方式

iOS页面间的传值细分有很多种,基本的传值方式有三种:委托Delegate传值.通知NSNotification传值.Block传值,其他在项目中可能会遇到的还有:UserDefault或文件方式传值.单例模式传值.通过设置属性传值,再有其他的传值方式没有遇到使用过在此不做说明.场景适合,自己使用舒服就是好的方式. 在iOS开发的过程中,常见的页面跳转传值方式大致可以分为两种,现归纳总结一下: 第一种:OneViewController页面跳转到TwoViewController页面(即顺传)

ios 页面传值

今天看了一下ios 页面传值的方式大致分为四种: 代理delegate block 通知 单例class 今天试了一下前三种,在这里记录一下 下面示例是有两个页面,每个页面都有一个按钮Button,点击第一个页面的按钮回调到第二个页面,再点击第二个页面回跳转道第一个页面,第一个按钮的标题变为第二个按钮传回的值. 代理delegate 代理似乎是我的心结,能用API 但是就是不会自己写,这也是今天会写传值的原因. 假设两个页面传值,协议类应该写在哪,代理应该定义在那个页面? 总结的时候我觉得可以这

iOS 页面传值的几种方式之NSNotificationCenter传值

接着上回说的iOS页面传值问题 传送门---------->iOS页面传值之代理传值 接下来我们说说NSNotificationCenter传值方式 在开始之前,我们首先得知道KVO模式 Key-Value Observing (KVO) 键值监听 就是说当你告诉通知中心一个Key 他会根据Value的变化做些事情,或者是获取一些数据 说上千回,不如用上一回. 我们在B控制器发送一个监听 [[NSNotificationCenter defaultCenter] postNotification