UI学习: 多界面传值的正向传值(属性传值)和反向传值(代理传值)
文章目录一、属性传值正向传值A → B原理实现步骤二、代理传值反向传值B → A为什么属性传值做不到反向传代理模式三要素数据流向实现步骤三、两种传值方式对比一、属性传值正向传值A → B原理在B 界面声明公开属性A 界面在跳转前给该属性赋值。适用于从前一个页面向后一个页面传递数据。A界面VCFirst ──push──▶ B界面VCSecond 传值方 接收方注意属性recievedText原文有拼写错误正确应为receivedText。实现步骤第一步在 VCSecond.h 中声明接收属性.h是头文件相当于这个类对外公开的接口说明书。把属性写在这里其他类 import 之后就能看到并访问它。如果写在.m的匿名分类里外部是访问不到的。属性修饰符选copy而不是strong是因为NSString有可能被传入一个NSMutableStringcopy能保证 B 拿到的是一份不可变的独立副本不会被外部意外修改。objc// VCSecond.h#importUIKit/UIKit.hinterfaceVCSecond:UIViewControllerproperty(nonatomic,copy)NSString*receivedText;// 接收从A传来的值end第二步在 VCSecond.m 中使用该属性在viewDidLoad里使用属性是安全的——此时控制器已经完成初始化A 在 push 之前已经完成赋值所以self.receivedText一定有值。不要在init方法里读取它那时候赋值还没发生。objc// VCSecond.m#importVCSecond.hinterfaceVCSecond()property(nonatomic,strong)UILabel*label;endimplementationVCSecond-(void)viewDidLoad{[superviewDidLoad];self.view.backgroundColor[UIColor whiteColor];self.label[[UILabel alloc]initWithFrame:CGRectMake(100,200,200,50)];self.label.textAlignmentNSTextAlignmentCenter;self.label.textself.receivedText;// 直接使用传入的值[self.view addSubview:self.label];}end第三步在 VCFirst.m 中赋值并跳转赋值和跳转的顺序很关键必须先赋值再 push。push 之后系统会调用 B 的viewDidLoad如果赋值在 push 之后B 读到的就是 nil。另外记得 import VCSecond.h否则编译器不知道vc.receivedText这个属性的存在会直接报错。objc// VCFirst.m#importVCFirst.h#importVCSecond.h// 必须导入才能访问 VCSecond 的属性interfaceVCFirst()property(nonatomic,strong)UITextField*textField;endimplementationVCFirst-(void)viewDidLoad{[superviewDidLoad];self.view.backgroundColor[UIColor whiteColor];self.textField[[UITextField alloc]initWithFrame:CGRectMake(100,200,200,40)];self.textField.borderStyleUITextBorderStyleRoundedRect;self.textField.placeholder请输入内容;[self.view addSubview:self.textField];UIButton*btn[UIButton buttonWithType:UIButtonTypeSystem];btn.frameCGRectMake(100,270,200,40);[btn setTitle:跳转到第二页forState:UIControlStateNormal];[btn addTarget:selfaction:selector(btnClick)forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btn];}-(void)btnClick{VCSecond*vc[[VCSecond alloc]init];vc.receivedTextself.textField.text;// 先赋值[self.navigationController pushViewController:vc animated:YES];// 后跳转}end二、代理传值反向传值B → A为什么属性传值做不到反向传A push 到 B 之后A 就进入了等待状态它不会主动做任何事。B 此时并没有持有 A 的引用所以 B 无法直接找到 A、给 A 的属性赋值。代理模式的核心思路是B 不直接操作 A而是通过调用一个约定好的方法来通知外界A 自己来实现这个方法、完成赋值。B 只负责喊一声我有数据了至于谁来处理、怎么处理B 不关心。代理模式三要素要素对应角色说明协议Protocol接口约定规定传值方法的格式委托方B 界面VCSecond定义协议持有代理引用在需要时调用方法代理人DelegateA 界面VCFirst遵守协议实现方法真正执行操作数据流向B界面VCSecond ──调用代理方法──▶ A界面VCFirst 委托方 代理人实现方法实现步骤第一步在 VCSecond.h 中定义协议并声明 delegate 属性协议就是一份合同规定了代理人必须实现哪些方法。把协议定义在 VCSecond.h 里是因为协议描述的是B 需要别人帮它做什么自然由 B 来声明。delegate属性用idVCSecondDelegate类型意思是任何遵守了这份协议的对象都可以做我的代理不限定具体类型灵活性更高。objc// VCSecond.h#importUIKit/UIKit.h// 定义协议protocolVCSecondDelegateNSObject-(void)vcSecond:(id)vcSecond didSendText:(NSString*)text;endinterfaceVCSecond:UIViewController// 声明 delegate 属性必须用 weakproperty(nonatomic,weak)idVCSecondDelegatedelegate;end为什么 delegate 必须用weak**A 持有 Bpush 进来的如果 B 再用strong持有 A作为 delegate两者就互相强引用谁也释放不了造成内存泄漏。用weak让 B 对 A 的引用不增加引用计数A 就能正常释放。第二步在 VCSecond.m 中触发代理方法B 在需要传值的时机这里是点击返回按钮时调用 delegate 的方法把数据推出去。调用前用respondsToSelector:判断代理是否实现了该方法这是一种防御性写法。如果 delegate 为 nil或者代理人没有实现这个方法直接调用会 crash加上这个判断就安全多了。objc// VCSecond.m#importVCSecond.hinterfaceVCSecond()property(nonatomic,strong)UITextField*textField;endimplementationVCSecond-(void)viewDidLoad{[superviewDidLoad];self.view.backgroundColor[UIColor orangeColor];self.textField[[UITextField alloc]initWithFrame:CGRectMake(100,200,200,40)];self.textField.borderStyleUITextBorderStyleRoundedRect;self.textField.placeholder输入要传回的内容;[self.view addSubview:self.textField];UIButton*btn[UIButton buttonWithType:UIButtonTypeSystem];btn.frameCGRectMake(100,270,200,40);[btn setTitle:返回并传值forState:UIControlStateNormal];[btn addTarget:selfaction:selector(backBtnClick)forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btn];}-(void)backBtnClick{// 先传值再 pop顺序不能反if([self.delegate respondsToSelector:selector(vcSecond:didSendText:)]){[self.delegate vcSecond:selfdidSendText:self.textField.text];}[self.navigationController popViewControllerAnimated:YES];}end第三步VCFirst 遵守协议设置代理实现方法遵守协议写在.h的尖括号里相当于公开声明我实现了这份合同。如果只在.m里遵守外部看不到有时会引起警告。设置vc.delegate self这一步非常容易遗漏——协议和方法都写好了但忘了指定代理人结果 delegate 一直是 nil方法永远不会被调用。objc// VCFirst.h#importUIKit/UIKit.h#importVCSecond.h// 导入头文件才能使用协议interfaceVCFirst:UIViewControllerVCSecondDelegate// 遵守协议endobjc// VCFirst.m#importVCFirst.hinterfaceVCFirst()property(nonatomic,strong)UILabel*label;endimplementationVCFirst-(void)viewDidLoad{[superviewDidLoad];self.view.backgroundColor[UIColor whiteColor];self.label[[UILabel alloc]initWithFrame:CGRectMake(100,200,200,50)];self.label.text等待传值...;self.label.textAlignmentNSTextAlignmentCenter;[self.view addSubview:self.label];UIButton*btn[UIButton buttonWithType:UIButtonTypeSystem];btn.frameCGRectMake(100,270,200,40);[btn setTitle:去第二页forState:UIControlStateNormal];[btn addTarget:selfaction:selector(btnClick)forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btn];}-(void)btnClick{VCSecond*vc[[VCSecond alloc]init];vc.delegateself;// 指定代理这步漏掉永远不会被调用[self.navigationController pushViewController:vc animated:YES];}// 实现协议方法B 调用时这里自动触发-(void)vcSecond:(id)vcSecond didSendText:(NSString*)text{self.label.texttext;}end三、两种传值方式对比两种方式本质上都是让另一个控制器持有数据只是持有的时机和方向不同。正向传值在跳转前完成简单直接反向传值依赖回调机制写法多几步但一旦理解了代理模式这套写法在 iOS 开发中会反复用到非常值得掌握。属性传值代理传值方向A → B正向B → A反向时机跳转前赋值返回时回调实现复杂度简单相对复杂适用场景传递初始数据传递结果/回调数据内存注意无特殊要求delegate 必须用weak

相关新闻

python学习8 之 【集合、datetime模块、字典】

python学习8 之 【集合、datetime模块、字典】

目录 1.集合 1.1.集合的特点 1.2.集合的创建 1.3.基本操作 1.4.集合运算 1.5.集合关系判断 1.6.frozenset 2.datetime 模块 2.1.主要类 3.字典 3.2.基础操作 3.3.视图和遍历 视图对象 3.4.字典操作 3.5.创建和转换 3.6.字典比较 3.7.字典排序输出 3.8.常用模…

2026/10/10 8:58:45 阅读更多 →
上海jsp网站建设:从入门到精通,揭秘高端企业官网背后的技术逻辑与用户体验优化策略

上海jsp网站建设:从入门到精通,揭秘高端企业官网背后的技术逻辑与用户体验优化策略

在如今的互联网时代,企业官方网站早已不再是简单的“网上名片”,而是品牌实力的延伸、业务转化的核心引擎以及客户信任的基石。特别是在上海这样一座国际化大都市,竞争尤为激烈,企业对于网站的要求也呈现出前所未有的高标准。提到网站开发技术,很多人首先想到的是WordPres…

2026/9/25 22:32:45 阅读更多 →
2026年8月智能仓储厂家:自动化智能货架仓储生产企业深度盘点

2026年8月智能仓储厂家:自动化智能货架仓储生产企业深度盘点

一、行业需求洞察:四大驱动力推动智能仓储进入黄金发展期2026年,中国智能制造与智慧物流迈入深度落地阶段,自动化智能货架仓储系统已从制造业"可选项"转变为新质生产力的标配基础设施。在土地成本攀升、人力成本高企、双碳政策倒逼…

2026/10/18 19:54:50 阅读更多 →

最新新闻

低空航拍路面裂缝检测数据集:VOC+YOLO双格式标注与训练实战

低空航拍路面裂缝检测数据集:VOC+YOLO双格式标注与训练实战

低空航拍路面裂缝类型检测数据集,这个项目我前后折腾了一个多月,最终整理出3391张带完整标注的有效样本,并按VOCYOLO双格式交付。起因很简单:市场上公开的路面裂缝数据集大多来自地面手持相机或车载视角,真正贴合无人机…

2026/10/19 19:47:09 阅读更多 →
为vLLM添加自定义模型推理支持:从权重转换到启动验证

为vLLM添加自定义模型推理支持:从权重转换到启动验证

模型训练收工的那一刻,通常是最开心的;接下去要把模型送上线,才是最磨人的。手里一个小众模型,训练时用的自定义框架,checkpoint 命名随心所欲,架构和主流模型有那么点像又不完全一样。你想用 vLLM 上线&am…

2026/10/19 19:47:09 阅读更多 →
开源代码审查工具 open-code-review:自动化预审与人工把关的工程实践

开源代码审查工具 open-code-review:自动化预审与人工把关的工程实践

代码审查这件事,不少团队都卡在同一个地方:流程定下来了,工具也上了,但审查质量始终靠人肉上下文硬扛。要么是 review 的人对业务不熟,提的comments全是 style 层面;要么是 reviewer 自己忙,拖了…

2026/10/19 19:47:09 阅读更多 →
开源代码评审工具实战:从规则引擎到插件化架构的设计与部署

开源代码评审工具实战:从规则引擎到插件化架构的设计与部署

1. 为什么我会自己动手写一个代码评审工具做了这么多年开发,代码评审这件事,我一直觉得是“人人都知道重要,但很难坚持做好”的环节。团队里 code review 做得松的,基本就是合并前点个通过;做得严的,又容易…

2026/10/19 19:47:09 阅读更多 →
LangChain智能体(Agent)实战指南:从ReAct到LangGraph

LangChain智能体(Agent)实战指南:从ReAct到LangGraph

聊LangChain,绕不开的就是Agent。用过ChatGPT的人都知道,模型本身再强也只是个“建议者”,你问它今天天气如何,它只能抱歉地说自己不知道实时数据。但Agent不一样,它把模型从“会说话的百科全书”变成了“会动手办事的…

2026/10/19 19:47:09 阅读更多 →
低剂量TEM图像去噪:非局部机制如何保住晶格细节

低剂量TEM图像去噪:非局部机制如何保住晶格细节

简介:面向深度学习去噪研究的TEM-NLnet项目Demo,定位为论文复现辅助资源,适合需要理解或应用深度去噪网络的研究者与开发者。压缩包共11个文件,以10个Python脚本为主,另含1个Markdown说明文档,整体仅14KB&a…

2026/10/19 19:46:07 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →