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

Swift中如何让B类调用委托A类所持C类实例的方法?

解决Class B调用Class A所持Class C实例方法的几种方案

我来帮你梳理几个Swift里常用的解决方案,都是针对这种委托链调用的场景:

方案1:修改协议,通过委托转发调用

这是最贴合原有委托设计思路的方案,我们可以调整ClassBDelegate协议,要么让它提供访问ClassC的入口,要么直接定义需要调用的方法,让ClassA内部转发给ClassC。

子方案1a:协议暴露ClassC实例

如果允许ClassB知晓ClassC的存在,可以让协议返回ClassC实例:

// 调整协议,添加获取ClassC的只读属性
protocol ClassBDelegate: class {
    var classC: ClassC { get }
}

class ClassC {
    func myFunc() {
        print("执行ClassC的myFunc方法")
    }
}

class ClassA: ClassBDelegate {
    // ClassA持有ClassC实例
    private let classCInstance = ClassC()
    
    // 实现协议要求的属性,返回内部的ClassC实例
    var classC: ClassC {
        return classCInstance
    }
}

class ClassB {
    weak var delegate: ClassBDelegate?
    
    func triggerAction() {
        // 现在可以通过协议拿到ClassC实例,再调用目标方法
        delegate?.classC.myFunc()
    }
}

子方案1b:协议直接定义方法,由ClassA转发

如果想降低耦合,不让ClassB知道ClassC的存在,可以直接把myFunc放到协议里,让ClassA实现时内部转发:

protocol ClassBDelegate: class {
    func myFunc() // 直接把需要调用的方法定义在协议中
}

class ClassA: ClassBDelegate {
    private let classCInstance = ClassC()
    
    // 实现协议方法,内部转发给ClassC的对应方法
    func myFunc() {
        classCInstance.myFunc()
    }
}

class ClassB {
    weak var delegate: ClassBDelegate?
    
    func triggerAction() {
        // 和原来的调用方式完全一致,不用修改ClassB的调用逻辑
        delegate?.myFunc()
    }
}

这个方式更推荐,因为ClassB只依赖抽象的协议,完全不需要关心ClassC的存在,符合面向抽象编程的原则。

方案2:用闭包替代委托(适合单一方法场景)

如果只是需要调用这一个方法,不想修改协议,可以给ClassB添加一个闭包属性,让ClassA初始化时把ClassC的方法绑定进去:

class ClassB {
    // 定义一个和myFunc签名一致的闭包属性
    var onMyFuncTriggered: (() -> Void)?
    
    func triggerAction() {
        // 直接调用闭包
        onMyFuncTriggered?()
    }
}

class ClassA {
    private let classCInstance = ClassC()
    let classB = ClassB()
    
    init() {
        // 绑定闭包,注意用[weak self]避免循环引用
        classB.onMyFuncTriggered = { [weak self] in
            self?.classCInstance.myFunc()
        }
    }
}

这个方案更轻量,不需要维护协议,但如果后续需要多个方法,会导致ClassB里的闭包属性越来越多,代码变得杂乱。

方案3:让ClassC直接作为ClassB的委托(谨慎使用)

如果业务逻辑允许,也可以跳过ClassA,直接让ClassC实现ClassBDelegate协议,然后把ClassC实例设为ClassB的delegate。但这种方式只适合ClassC和ClassB的逻辑直接相关的场景,否则会破坏原有的代码结构,增加耦合度。


内容的提问来源于stack exchange,提问作者Chewie The Chorkie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:25:13