You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅地从多层嵌套自定义视图向控制器传递点击回调消息?

多层嵌套视图的按钮回调传递方案解析

场景回顾:某控制器包含redCustomView,该视图内嵌套greenCustomView,而greenCustomView内又包含带有按钮的blueCustomView。需求是:当按钮被点击时,把事件回调传递给最上层的控制器。

下面我来拆解几种常见实现方案的优缺点:

1. Block 逐层传递回调

  • 实现方式:从最内层的blueCustomView开始,定义一个按钮点击的block属性。当按钮触发点击事件时,直接调用这个block;接着greenCustomView在持有blueCustomView后,设置它的block,在回调里触发自己定义的对应block;以此类推,redCustomView也重复这个逻辑,最终控制器在配置redCustomView时,通过设置它的block拿到最内层按钮的点击事件。
  • 存在问题:代码冗余严重!每一层视图都要重复定义block属性、编写传递逻辑,层级越多,重复代码越多。另外如果不小心处理不好循环引用(比如block里强引用了当前视图,而视图又被上层持有),还会引发内存泄漏问题。

2. Delegate 逐层传递回调

  • 实现方式:和block逻辑类似,采用逐层代理的方式。blueCustomView先定义一套代理协议,声明按钮点击的代理方法;greenCustomView遵守这个协议并实现代理方法,同时自己也定义一套代理协议;redCustomView同样遵守greenCustomView的协议并实现方法,最后控制器遵守redCustomView的代理协议,就能拿到回调。
  • 存在问题:同样面临代码冗余的问题,每一层都要写代理协议、声明代理属性、实现代理方法,层级多了之后,协议和代理逻辑会散在各个视图文件里,后期维护起来非常麻烦,而且代理方法的调用链也不容易追踪。

3. Notification 直接传递回调

  • 实现方式:跳过中间所有视图层,在blueCustomView的按钮点击事件里,发送一个自定义的通知;然后在控制器的viewDidLoad(或合适的生命周期方法)里注册这个通知,就能直接收到按钮点击的回调。
  • 存在问题:
    • 通知是全局广播机制,容易出现通知名冲突的问题,如果项目里其他模块也用了同一个通知名,会导致意外的回调触发;
    • 调试难度高,你很难直观地追踪到这个通知是谁发送的、有哪些对象在接收,排查问题时要花更多时间;
    • 如果控制器没有在合适的时机(比如dealloc或viewWillDisappear)移除通知注册,还可能导致野指针崩溃或者内存泄漏的风险。

内容的提问来源于stack exchange,提问作者无夜之星辰

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:42:36