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

Swift中通过代理关闭视图控制器的实现方案咨询

关于Swift代理关闭视图控制器方案的合理性分析

首先,这个方案的核心思路是合理的——利用代理模式解耦视图控制器和关闭逻辑,而且给代理属性加上weak修饰符也避免了循环引用,这部分完全符合Swift代理设计的最佳实践。不过细节上还有一些可以优化的地方,下面具体拆解:

现有实现的可取之处

  • 遵循了代理模式的核心原则:将视图控制器的关闭逻辑委托给外部对象,避免视图控制器耦合过多业务逻辑
  • 给代理属性添加weak修饰,防止循环引用(因为协议限定了class类型,weak可以正常使用)

可以优化的细节点

  1. 协议命名更具语义化
    目前的MyDelegate和MyProtocol命名太模糊,建议根据功能命名,可读性会强很多:

    protocol ViewControllerCloseDelegate: class {
        func closeViewController()
    }
    protocol ViewControllerDelegateHolder: class {
        weak var closeDelegate: ViewControllerCloseDelegate? { get set }
    }
    
  2. 修正MyProtocol的逻辑指向
    你的代码里MyProtocol定义了weak var delegate: SomeClass? {get set},这里有个逻辑偏差:代理协议通常是让视图控制器去遵守,而不是把代理属性的类型设为SomeClass。正确的做法是让你的UIViewController子类遵守ViewControllerDelegateHolder(原MyProtocol),这样SomeClass作为代理才能正确赋值。

  3. 给视图控制器添加类型约束
    你的SomeClass初始化时接收的是UIViewController,但普通的UIViewController并没有delegate属性,应该约束为遵守代理协议的视图控制器类型,避免编译警告同时保证类型安全:

    class SomeClass: ViewControllerCloseDelegate {
        var myViewController: ViewControllerDelegateHolder & UIViewController
        
        init(myViewController: ViewControllerDelegateHolder & UIViewController){
            self.myViewController = myViewController
            myViewController.closeDelegate = self
        }
        
        func closeViewController() {
            myViewController.dismiss(animated: true, completion: nil)
        }
    }
    
  4. 提升关闭逻辑的安全性
    在调用dismiss之前,可以先判断视图控制器是否处于可关闭状态,避免无效调用:

    func closeViewController() {
        if myViewController.presentingViewController != nil {
            myViewController.dismiss(animated: true, completion: nil)
        }
    }
    

总结

整体的代理思路是没问题的,只要把上面的细节优化一下,就是一个规范且健壮的实现啦。

内容的提问来源于stack exchange,提问作者Human Cyborg Relations

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:22:27