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

协议扩展方法被调用而非视图控制器实现,可选方法异常求助

问题分析与解决方案

这确实是Swift协议扩展里一个很容易踩的坑,我来帮你理清楚问题根源和解决办法:

问题出在哪?

你的theOptionalMethod只在协议扩展里提供了默认实现,但并没有被声明为ViewDelegate协议的必须要求(也就是没写在协议的大括号内)。

在Swift中,当你通过协议类型的变量(比如你的delegate: ViewDelegate?)调用一个方法时:

  • 如果这个方法是协议的要求(写在协议定义里),编译器会做动态派发,会去查找具体实现类的自定义实现,这也是theNOTOptionalMethod工作正常的原因;
  • 如果这个方法只是协议扩展里的默认实现、没有被列为协议要求,编译器会直接调用扩展里的代码,不会去检查具体类有没有自定义实现——因为协议本身没要求这个方法存在,编译器不知道子类可能会实现它。

怎么解决?

只需要把theOptionalMethod添加到ViewDelegate协议的要求中即可,即使你在扩展里保留默认实现,编译器也会为它做动态派发:

protocol ViewDelegate: class { 
    func theNOTOptionalMethod() 
    func theOptionalMethod() // 将该方法加入协议要求
} 

extension ViewDelegate { 
    func theOptionalMethod(){ 
        print (" method in extension Called") 
    } 
} 

这样修改后,当someAction触发调用deleage?.theOptionalMethod()时,就会正确执行someCustomizedVC里的自定义实现,打印出你期望的内容了。

补充说明

如果你不想把这个方法列为协议的强制要求(比如希望子类可以选择不实现),也可以用@objc协议配合可选方法的方式:

@objc protocol ViewDelegate: class { 
    func theNOTOptionalMethod() 
    @objc optional func theOptionalMethod() 
} 

// 扩展里的默认实现可以去掉,或者保留(但@objc协议的可选方法默认实现需要注意调用方式)
class someCustomizedVC: UIViewController, ViewDelegate { 
    // ...
    func theOptionalMethod() { 
        print (" method in otherCustomizedClass called ") 
    } 
}

不过这种方式更适合和OC代码交互的场景,纯Swift代码里更推荐第一种把方法加入协议要求+扩展默认实现的方案,逻辑更清晰。

内容的提问来源于stack exchange,提问作者Ian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:56:20