Objective-Cのレガシーコードがあり、次のようなメソッドを宣言しています。
- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error
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 言語でテスト済み。)BOOL
bool
その理由は、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
そして「期待どおり」に動作するようです。ただし、この属性に関する公式ドキュメントは見つからなかったため、これに頼るのは得策ではないかもしれません。