2017-07-02 3 views
0

エラーの原因となったコードを再試行するオプション付きでUIAlertControllerを使用してエラーを処理する方法を工夫しています。Swift:エスケープされたクロージャーを投げたときのエラー処理(混乱)

func handleError(_ closure: @escaping() throws -> Void) { 
    do { 
    try closure() 
    } catch { 
    print(error) 
    let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert) 
    let retry = UIAlertAction(title: "Retry", style: .default, handler: {(_: UIAlertAction) in self.handleError(closure)}) 
    alert.addAction(retry) 
    let cancel = UIAlertAction(title: "Cancel", style: .cancel) 
    alert.addAction(cancel) 
    present(alert, animated: true) 
    } 
} 

は、しかし、ちょうどこのを見て、それらを防ぐよりも多くのエラーを引き起こすように思える:私は何とか実際に動作するこの巨大な混乱を思い付きました。これを簡単にするか、あまり混乱させないために私ができることはありますか?私はなぜ@escapingパートが必要なのか理解できませんが(コンパイラは私に言います)、なぜUIAlertActionクロージャの空白の引数を指定する必要があるのですか?

これは解決策があまりにも悪くないという安心感が必要です。

答えて

1

@escapingのアイデアは、クロージャが非同期呼び出しで実行されることに気付きました。この方法で考えてみましょう。あなた自身が開発していない関数を呼び出す必要があり、クロージャを渡す必要があるとします。ここで、クロージャが同期呼び出しとして実行されることを期待しているとします。それが同期呼び出しとしてのみ使用されるかどうかをどのように知ることができますか?迅速に@エスケープアノテーションを使用して、この保証を得てください。関数が非同期呼び出しで使用される場合は、関数のシグネチャでこれを通知する必要があります。あなたのケースでは、クロージャを呼び出すためのユーザアクションを待つAlertControllerに関数を渡しています。

空白の引数については、実際には空白の引数ではなく、関数の署名です。ここでは、関数を引数として受け取ることをコンパイラに指示しています。この関数は引数を持たず何も返しませんが、例外をスローする可能性があります。迅速に、関数には型があります。文字列を引数として受け取り、ブール値を返す関数の型は(String)-> Boolです。空のパラメータでは、引数として受け入れる関数のタイプを定義しています。この場合、関数タイプは() ->()です。これは、()と要約することができ、引数を持たず何も返しない関数を意味します。

ファンクションタイプの詳細については、hereをご覧ください。

ところで、私はあなたのコードが正しいと思います。私は何の問題も見ませんが、あなたに適切な応答を与えるために、私はあなたの閉鎖になるものを知る必要があります。

+0

クロージャは、その前に「try」が必要なコードであればどのようなコードでも構いません。私はすべての種類のもののためにその場所全体にそれを使用したい – MysteryPancake

+0

試着との関係はありません。例外をスローする可能性のある関数を呼び出す前にtryを使用する必要があります。操作が例外をスローできる場合(制御されたエラーと考える)、tryを使用する必要があります。クロージャは、他の関数への引数として渡すことのできる特別なタイプの関数です。 –

+0

このコードのうち、私が単純化できる部分はありますか?私は主に(_:UIAlertAction)の部分について考えています – MysteryPancake

関連する問題