![](/img/trans.png)
[英]Throwing method cannot be a member of an @objc protocol because it returns a value of type '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
返回類型,因此錯誤是相互排斥的。 我該如何解決這個問題,為什么我們需要Bool
和throw
在這里?
為什么我們需要
Bool
和throw
這個問題歸結為您實際上想要實現的目標。 我同意給定的行為是不一致的,此外,Swift 橋接規則在過去發生了變化,將來可能會發生變化,因此您目前所破壞的,可以在可預見的未來變成工作樣本。 但是現在,這個錯誤說明了一切:
Throwing 方法不能是 @objc 要求的實現,因為它返回
Bool
類型的值; 返回Void
或橋接到 Objective-C class 的類型
換句話說,如果您的 Swift 方法標有throws
關鍵字(並暴露給 Objective-C 運行時),它必須返回一個普通的 Objective-C 類型(不是神奇地橋接 Swift 結構,如Int
、 Bool
、 Double
等。它必須是NSObject
、 NSProxy
或其他 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.