簡體   English   中英

Throwing 方法不能是 @objc 要求的實現,因為它返回類型為“Bool”的值

[英]Throwing method cannot be an implementation of an @objc requirement because it returns a value of type `Bool`

我有IKabaSDK.h ,它是一個 (Objective-C) 協議:

@import Foundation;
@import MobileSdk;
    
NS_ASSUME_NONNULL_BEGIN
    
@protocol IKabaSDK <NSObject>
     
- (BOOL)isStarted:(NSError* _Nullable __autoreleasing * _Nullable)error
__attribute__((swift_error(nonnull_error)))
NS_SWIFT_NAME(isStarted());

我有一個 (Swift) class KabaSDKThunk ,其中實現了上述協議:

class KabaSDKThunk: NSObject, IKabaSDK {
    func isStarted() throws -> Bool {
        do {
            try sdk.isStarted()
            print("thunk getIsStarted")
        } catch {
            print("thunk getIsStarted throws \(error)")
            throw error
        }
    }
    ...
}

Xcode 在我的實施旁邊給了我這兩個錯誤:

  • @objc方法isStarted()不滿足@objc協議IKabaSDK的要求
  • Throwing 方法不能是 @objc 要求的實現,因為它返回Bool類型的值; 返回Void或橋接到 Objective-C class 的類型

如果我不添加Bool它會抱怨KabaSDKThunk不符合協議IKabaSDK並建議添加Bool返回類型,因此錯誤是相互排斥的。 我該如何解決這個問題,為什么我們需要Boolthrow在這里?

為什么我們需要Boolthrow

這個問題歸結為您實際上想要實現的目標。 我同意給定的行為是不一致的,此外,Swift 橋接規則在過去發生了變化,將來可能會發生變化,因此您目前所破壞的,可以在可預見的未來變成工作樣本。 但是現在,這個錯誤說明了一切:

Throwing 方法不能是 @objc 要求的實現,因為它返回Bool類型的值; 返回Void或橋接到 Objective-C class 的類型

換句話說,如果您的 Swift 方法標有throws關鍵字(並暴露給 Objective-C 運行時),它必須返回一個普通的 Objective-C 類型(不是神奇地橋接 Swift 結構,如IntBoolDouble等。它必須是NSObjectNSProxy或其他 Objective-C 實體的子類)或不返回任何內容。 時期。 把它作為一個規則(至少現在)。 PS這種特定情況確實看起來像一個 LLVM 錯誤,因為相同的一組要求在應用於非協議 Objective-C 方法時工作得很好(在此處提交,因此社區有機會審查它))

話雖如此,這種情況的正確解決方法取決於您的最終目標。

“常規”失敗方法

這里的“常規”是指 Cocoa/Cocoa touch 程序員通常期望的合同。 在這種情況下,具有以下簽名的方法:

- (BOOL)failableMethodWithError:(NSError **)error;

通常意味着在返回NO值的任何地方失敗(在 Objective-C 的世界中)。 Swift 處理像NSError **這樣的間接參數並不常見,所以為了保持一致,這些方法橋接如下:

func failableMethod() throws

您可以在關於導入的 Cocoa 錯誤參數文檔中閱讀有關此約定的更多信息。

帶有swift_error(nonnull_error)屬性的保留返回類型的失敗方法

如果您想保留返回類型和可失敗簽名,您有兩個選擇。 首先是給方法swift_error(nonnull_error)屬性。 但是在這種情況下,為了遵守現有的橋接規則,您的方法必須具有“橋接”到 Objective-C class 的類型,例如NSNumber *

- (NSNumber *)failableMethodWithError:(NSError ** _Nullable)error __attribute__((swift_error(nonnull_error)));

以下是如何在 Swift 中實現這種方法:

func failableMethod() throws -> NSNumber {
    return NSNumber(booleanLiteral: false)
}

帶有swift_error(none)屬性的保留返回類型的失敗方法

保留返回類型的另一種選擇是通過使用swift_error(none)屬性完全禁用 Objective-C - Swift 錯誤簽名轉換:

- (BOOL)failableMethodWithError:(NSError ** _Nullable)error __attribute__((swift_error(none)));

在這種情況下,您可以從可失敗方法返回一個標量類型,但同時您將不得不處理NSErrorPointer類型:

func failableMethodWithError(_ error: NSErrorPointer) -> Bool {
    if (/*error condition */) {
        error?.pointee = NSError(domain: TDWErrorDomain, code: TDWErrorDomainErrorCode)
    }
    return true
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM