【OC】多界面传值总结
【OC】多界面传值总结文章目录【OC】多界面传值总结属性传值(A-B)代理传值(B-A)Block传值B-A通知传值任意方向KVO传值观察属性变化在学习iOS 开发的知识过程中把几种常见的多界面传值方式梳理了一下记录在这里方便以后回顾属性传值(A-B)这是一种正向传值也是最简单的一种就是从 A 界面跳转到 B 界面的时候把数据直接塞给 B思路在 B 控制器里定义一个属性跳转之前给它赋值B 拿到之后用就行了// SecondViewController.h#importUIKit/UIKit.hinterfaceSecondViewController:UIViewControllerproperty(nonatomic,copy)NSString*receiveStr;end// SecondViewController.m-(void)viewDidLoad{[superviewDidLoad];// 直接用 receiveStr 就行NSLog(%,self.receiveStr);self.titleLabel.textself.receiveStr;}// FirstViewController.m-(void)jumpToSecond{SecondViewController*secondVC[[SecondViewController alloc]init];secondVC.receiveStr我是从第一个界面传来的;[self.navigationController pushViewController:secondVC animated:YES];}这个最简单正向传没啥问题但是反向传B → A就不行了代理传值(B-A)这是一种反向传值比如从 B 把数据传回给 A思路B 里面定义一个协议A 来遵守这个协议B 在需要传值的时候调用代理方法A 实现这个方法拿数据FirstViewController.m// 遵守协议interfaceFirstViewController()SecondVCDelegateend// 跳转的时候设置代理-(void)jumpToSecond{SecondViewController*secondVC[[SecondViewController alloc]init];secondVC.delegateself;[self.navigationController pushViewController:secondVC animated:YES];}// 实现代理方法-(void)sendData:(NSString*)data{NSLog(B 传回来的数据%,data);self.label.textdata;}SecondViewController.h#importUIKit/UIKit.h// 定义协议protocolSecondVCDelegateNSObject-(void)sendData:(NSString*)data;endinterfaceSecondViewController:UIViewController// 代理属性用 weak 防止循环引用property(nonatomic,weak)idSecondVCDelegatedelegate;endSecondViewController.m// 点击按钮传值回去-(void)sendBtnClick{if([self.delegate respondsToSelector:selector(sendData:)]){[self.delegate sendData:这是从 B 传回来的数据];}[self.navigationController popViewControllerAnimated:YES];}Block传值B-ABlock 传值和代理传值效果差不多也是反向传但是写起来比代理简洁很多思路B 里面定义一个 block 属性A 跳转到 B 之前给这个 block 赋值实现具体逻辑B 在合适的时候调用这个 block 把数据传出去SecondViewController.h#importUIKit/UIKit.h// 定义 block 类型typedefvoid(^SendDataBlock)(NSString*data);interfaceSecondViewController:UIViewControllerproperty(nonatomic,copy)SendDataBlock sendBlock;endSecondViewController.m-(void)sendBtnClick{// 调用 block 传数据if(self.sendBlock){self.sendBlock(这是 Block 传回来的数据);}[self.navigationController popViewControllerAnimated:YES];}FirstViewController.m-(void)jumpToSecond{SecondViewController*secondVC[[SecondViewController alloc]init];// 给 block 赋值在这里写好回调逻辑secondVC.sendBlock^(NSString*data){NSLog(Block 收到数据%,data);self.label.textdata;};[self.navigationController pushViewController:secondVC animated:YES];}⚠️注意循环引用block 里面用了self如果secondVC也强引用了 A就会形成循环引用所以最好通过弱引用打破循环引用__weaktypeof(self)weakSelfself;secondVC.sendBlock^(NSString*data){NSLog(Block 收到数据%,data);weakSelf.label.textdata;};通知传值任意方向通知这个机制比较灵活不只是两个界面之间一对多都可以适合那种不好直接建立联系的两个模块之间通信思路发通知的地方 post监听的地方 addObserver然后处理就行接收方比如 A先注册监听-(void)viewDidLoad{[superviewDidLoad];// 注册通知[[NSNotificationCenter defaultCenter]addObserver:selfselector:selector(receiveNotification:)name:SendDataNotificationobject:nil];}// 接收到通知的处理方法-(void)receiveNotification:(NSNotification*)noti{NSString*datanoti.userInfo[data];NSLog(收到通知数据是%,data);self.label.textdata;}// 记得移除不然会出问题-(void)dealloc{[[NSNotificationCenter defaultCenter]removeObserver:self];}发送方B发通知-(void)sendBtnClick{NSDictionary*userInfo{data:这是通知传过来的数据};[[NSNotificationCenter defaultCenter]postNotificationName:SendDataNotificationobject:nil userInfo:userInfo];}但是通知滥用的话代码逻辑会很乱不好追踪所以能用代理就用代理通知用来处理那种远距离的通信KVO传值观察属性变化KVOKey-Value Observing严格来说不算传值更像是观察某个对象属性的变化当被观察的属性值改变时观察者会自动收到通知思路A 观察 B 的某个属性B 的属性一变A 就知道了。被观察的对象B 里有一个属性// SecondViewController.hproperty(nonatomic,copy)NSString*observeStr;A 添加观察-(void)viewDidLoad{[superviewDidLoad];// 假设 self.secondVC 是持有的 B 对象[self.secondVC addObserver:selfforKeyPath:observeStroptions:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];}// 属性变化时会调这个方法-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context{if([keyPath isEqualToString:observeStr]){NSString*newValuechange[NSKeyValueChangeNewKey];NSLog(observeStr 变了新值是%,newValue);}}// 移除观察不然会崩-(void)dealloc{[self.secondVC removeObserver:selfforKeyPath:observeStr];}B 那边改属性值// 直接改KVO 会自动触发self.observeStr新的数据;KVO 感觉平时用的不多一般在需要监听 model 属性变化的时候会用界面传值用这个稍微有点绕实际开发中正向传值一般用属性反向传值优先考虑 Block需要一对多广播的用通知KVO 更多用在数据层的监听代理也很常用特别是 UIKit 里的那些系统组件基本都是代理模式以上是自己的一些理解如果有说错的地方欢迎指正
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2587314.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!