我有這個運行良好的代碼:
public protocol PermissionProvider {
static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
}
extension AVCaptureDevice: PermissionProvider {}
現在我需要將協議暴露給 Objc 運行時:
@objc // added this attribute
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 和 swift 之間的一些命名約定有關。我想知道如何修復編譯錯誤?
我引入這個協議的原因是,我需要對這個“權限提供者”進行單元測驗和注入。而我需要將其暴露給 objc 的原因是,一些呼叫者仍在 ObjC 中
編輯:
我創建了一個空專案,然后用上面的代碼創建了一個新檔案,并得到了錯誤

uj5u.com熱心網友回復:
在協議方法上添加 @objc 屬性以指定要暴露給 Objective-C 的不同方法名稱,在這種情況下,將其與AVCaptureDevice( authorizationStatusForMediaType:) 的相關方法匹配:
@objc // added this attribute
public protocol PermissionProvider {
@objc(authorizationStatusForMediaType:) static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
}
extension AVCaptureDevice: PermissionProvider {}
為什么?
當 Objective-C 方法映射到 Swift 時,與相應引數型別匹配的引數描述會被刪減(參見SE-0005 'Better Translation of Objective-C APIs into Swift'),但是當 Swift 映射到 Objective-C 時相應的“去修剪”不會發生。
例如,如果在 Objective-C 中我們定義了:
- (NappingStatus)nappingStatusForKoala:(Koala *)koala;
- (NappingStatus)nappingStatusForEchidna:(Koala *)koala;
當映射到 Swift 中時,這些將變為:
func nappingStatus(for: Koala) -> NappingStatus
func nappingStatus(forEchidna: Koala) -> NappingStatus
請注意,第一種方法Koala已從引數名稱中洗掉,因為它與它所描述的引數的型別匹配,但在第二種方法Echidna中沒有被洗掉,因為這與它所描述的引數的型別不匹配(考拉)。
當從 Swift 映射到 Objective-C 時,這種修剪的逆轉不會發生。例如,如果在 Swift 中我們定義了
func nappingStatus(for: Koala) -> NappingStatus
當映射到 Objective-C 時,它將變為:
- (NappingStatus)nappingStatusFor:(Koala *)koala;
因此,對于您的情況,Objective-C 中的 AVCaptureDevice 方法是:
(AVAuthorizationStatus)authorizationStatusForMediaType:(AVMediaType)mediaType;
在 Swift 中被映射到(注意 MediaType 被修剪):
class func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
但是您的協議方法,在 Swift 中是:
static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
當映射到 Objective-C 時將是(注意 MediaType 不是 `de-pruned'):
(AVAuthorizationStatus)authorizationStatusFor:(AVMediaType)mediaType;
這與 AVCaptureDevice 中的 Objective-C 方法不匹配,因此我們只需通過 @objc 屬性提供正確的 Objective-C 方法名稱:
@objc(authorizationStatusForMediaType:) static func authorizationStatus(for mediaType: AVMediaType) -> AVAuthorizationStatus
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/496058.html
