上一篇讲了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