私はいくつかの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"メソッドに変換するためにさらに何かが必要ですか?
BOOL
または(nullable)オブジェクトを返すObjective-Cメソッドのみが、Swiftのスローメソッドに変換されます。
その理由は、Cocoaメソッドは常にメソッドの失敗を示すために戻り値NO
またはnil
を使用し、notエラーを設定するだけだからです。オブジェクト。これは エラーオブジェクトの使用と作成 に記載されています:
重要:成功または失敗は、メソッドの戻り値によって示されます。 Cocoaエラードメイン内のエラーオブジェクトを間接的に返すCocoaメソッドは、メソッドが直接nilまたはNOを返すことによって失敗を示した場合、そのようなオブジェクトを返すことが保証されていますが、 NSErrorオブジェクト。
たとえば、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;
NS_ASSUME_NONNULL_END
@end
Swift asにマップされます
public class OClass : NSObject {
public func doSomethingWithArgument1(x: Int32, error: NSErrorPointer)
public func doSomethingWithArgument2(x: Int32) throws
public func doSomethingWithArgument3(x: Int32, error: NSErrorPointer) -> String
public func doSomethingWithArgument4(x: Int32) throws -> String
}
メソッドのインターフェースを変更できる場合は、成功または失敗を示すブール戻り値を追加する必要があります。
それ以外の場合は、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 as as
public func doSomethingWithArgument5(x: Int32) throws
そして、「期待どおりに」動作するようです。ただし、この属性に関する公式のドキュメントが見つからなかったため、これに依存するのは得策ではないかもしれません。
エラーをスローするかどうかをランタイムに通知するには、メソッドにBOOL
を返すようにする必要があります。また、エラーパラメータに__autoreleasing
を追加して、使用する前にARCが誤ってエラーを解放しないようにする必要があります。
- (BOOL)doSomethingWithArgument:(ArgType)argument error:(NSError * __autoreleasing *)error
次に、Swiftからこのように呼び出すことができます:
do {
object.doSomethingWithArgument(someArgument)
} catch let err as NSError {
print("Error: \(err)")
}