Swift面向协议编程中向ObjC暴露协议报selector不匹配错误如何修复
@objc协议适配AVCaptureDevice权限方法编译错误修复
问题复现
初始可正常运行的Swift代码:
import AVFoundation public protocol PermissionProvider { static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus } extension AVCaptureDevice: PermissionProvider {}
为了让协议可被Objective-C运行时识别、供存量ObjC逻辑调用,给协议添加@objc标记:
import AVFoundation @objc public protocol PermissionProvider { static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus } extension AVCaptureDevice: PermissionProvider {}
修改后触发编译错误:
AVFoundation.AVCaptureDevice:4:21: error: Objective-C method 'authorizationStatusForMediaType:' provided by method 'authorizationStatus(for:)' does not match the requirement's selector ('authorizationStatusFor:') open class func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
该问题可在空项目中稳定复现,引入协议的核心目的是支撑单元测试中的权限依赖注入。
根因分析
@objc协议的方法匹配是严格基于Objective-C selector的:
- Swift默认对
authorizationStatus(for:)方法生成的ObjC selector为authorizationStatusFor:(第一个参数标签for会直接拼接在方法名后,省略参数的实际语义名) - 系统
AVCaptureDevice自带的同名权限方法,原生Objective-C selector为authorizationStatusForMediaType:
二者selector不匹配,因此系统类的原生方法无法满足协议要求,触发编译报错。
修复代码
给协议内的方法显式指定和系统方法完全一致的ObjC selector即可,无需额外写扩展实现逻辑:
import AVFoundation @objc public protocol PermissionProvider { @objc(authorizationStatusForMediaType:) static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus } extension AVCaptureDevice: PermissionProvider {}
修复后:
- 编译可正常通过,
AVCaptureDevice自动满足协议要求 - Swift侧仍然可以使用原生
authorizationStatus(for:)的命名风格调用方法,不需要修改现有Swift代码 - 协议可正常被Objective-C代码识别调用,不影响存量ObjC逻辑
- 单元测试的依赖注入逻辑完全不受影响
内容的提问来源于stack exchange,提问作者OMGPOP
相关产品推荐
相关产品推荐

