web-dev-qa-db-ja.com

パラメータの受け渡しでSwift 4のコンパイルエラー

Xcode 9 Beta 3で サードパーティライブラリ を使用しました。完了呼び出しで次のエラーが発生します。このエラーを解決できません。

DispatchQueue.main.asyncAfter(deadline: .now() + delay) { 
    self.animationView?.alpha = 0
    self.containerView.alpha  = 1
    completion?()    // -> Error: Missing argument parameter #1 in call.   
}

そして、完了関数で次の警告が表示されます。

func openAnimation(_ completion: ((Void) -> Void)?) {    
    // -> Warning: When calling this function in Swift 4 or later, you must pass a '()' Tuple; did you mean for the input type to be '()'?
}    
11
yaali

Swift 4)では、タプルはこれまで以上に厳密に扱われます。

このクロージャータイプ:(Void)->Voidはクロージャを意味します

  • 型がVoidである単一の引数を取ります
  • Voidを返します。これは、値を返さないことを意味します

したがって、次のいずれかを試してください。

タイプVoidの値をクロージャに渡します。 (空のタプル()Voidの唯一のインスタンスです。)

completion?(())

または:

パラメータcompletionのタイプを変更します。

func openAnimation(_ completion: (() -> Void)?) {
    //...
}

2つのタイプを覚えておいてください(Void)->Voidおよび()->VoidはSwift 3でも異なります。したがって、引数なしでクロージャタイプを表す場合は、後者が適切です

この変更は SE-0029関数適用から暗黙のタプルスプラット動作を削除する の一部であり、Swift 3で実装されていると言われていますが、Swift 3は完全には実装していません。


ここでは、Playgroundで違いを確認できる簡単な確認コードを紹介します。

import Foundation

//### Compiles in Swift 3, error and warning in Swift 4
class MyClass3 {

    func openAnimation(_ completion: ((Void) -> Void)?) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {

            completion?()
        }
    }

}

//### Compiles both in Swift 3 & 4
class MyClass4 {

    func openAnimation(_ completion: (() -> Void)?) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {

            completion?()
        }
    }

}
22
OOPer