Swift は Objective-C NSError** を throws に変換しません 質問する

Swift は Objective-C NSError** を throws に変換しません 質問する

Objective-Cのレガシーコードがあり、次のようなメソッドを宣言しています。

- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error

ここに書かれているようにhttps://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html

Swift は、エラーを生成する Objective-C メソッドを、Swift のネイティブ エラー処理機能に従ってエラーをスローするメソッドに自動的に変換します。

しかし、私のプロジェクトでは、記述されているメソッドは次のように呼び出されます。

object.doSomething(argument: ArgType, error: NSErrorPointer)

さらに、次のように使用しようとすると、ランタイム例外がスローされます。

let errorPtr = NSErrorPointer()
object.doSomething(argumentValue, error: errorPtr)

Objective-C の「NSError **」メソッドを Swift の「trows」メソッドに変換するには、何か他に必要なものがありますか?

ベストアンサー1

Objective-Cメソッドのみがスロー メソッドに変換され、 (小文字ではない) または null 許容オブジェクトをSwift返します。(Xcode 11.7 および Swift 5 言語でテスト済み。)BOOLbool

その理由は、Cocoaメソッドは常に戻り値を使用するNOか、nilメソッドの失敗を示すためであり、ないエラーオブジェクトを設定するだけです。これはエラーオブジェクトの使用と作成:

重要:成功または失敗は、メソッドの戻り値によって示されます。Cocoa エラー ドメインで間接的にエラー オブジェクトを返す Cocoa メソッドは、メソッドが直接 nil または NO を返すことによって失敗を示す場合、そのようなオブジェクトを返すことが保証されていますが、NSError オブジェクトを使用して何かを行う前に、戻り値が nil または NO であることを常に確認する必要があります。

例えば、Objective-Cインターフェース

@interface OClass : NSObject

NS_ASSUME_NONNULL_BEGIN

-(void)doSomethingWithArgument1:(int) x error:(NSError **)error;
-(BOOL)doSomethingWithArgument2:(int) x error:(NSError **)error;
-(NSString *)doSomethingWithArgument3:(int) x error:(NSError **)error;
-(NSString * _Nullable)doSomethingWithArgument4:(int) x error:(NSError **)error;
-(BOOL)doSomething:(NSError **)error;

NS_ASSUME_NONNULL_END

@end

Swiftでは次のようにマッピングされます

open class OClass : NSObject {

    open func doSomethingWithArgument1(x: Int32, error: NSErrorPointer)
    open func doSomethingWithArgument2(x: Int32) throws
    open func doSomethingWithArgument3(x: Int32, error: NSErrorPointer) -> String
    open func doSomethingWithArgument4(x: Int32) throws -> String
    open func doSomething() throws
}

メソッドのインターフェースを変更できる場合は、成功または失敗を示すブール値の戻り値を追加する必要があります。

それ以外の場合はSwiftから次のように呼び出すことになります。

var error : NSError?
object.doSomethingWithArgument(argumentValue, error: &error)
if let theError = error {
    print(theError)
}

述べる:

Clang には、Swift で関数にエラーをスローさせる属性があることがわかりました。

-(void)doSomethingWithArgument5:(int) x error:(NSError **)error
  __attribute__((swift_error(nonnull_error)));

Swiftでは次のようにマッピングされます

public func doSomethingWithArgument5(x: Int32) throws

そして「期待どおり」に動作するようです。ただし、この属性に関する公式ドキュメントは見つからなかったため、これに頼るのは得策ではないかもしれません。

おすすめ記事