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

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的:

  1. Swift默认对authorizationStatus(for:)方法生成的ObjC selector为authorizationStatusFor:(第一个参数标签for会直接拼接在方法名后,省略参数的实际语义名)
  2. 系统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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:15:17