2017-07-22 8 views
2

私は、カテゴリクラスのリストを反復し、最後のすべてのカテゴリから項目を返すメソッドを持っています。 このような単純なコードを見て:とても良い、これまでSwift - オプションパラメータが期待どおりに機能しない

iterateMyCategoriesItems { (category) in 

    // doing something here with every category... 
} 

を、今、私は、このメソッドにオプションの完了を追加したいので、私はにコードを変更:

func iterateMyCategoriesItems(item:(_ category:Category) -> Void) 
{ 
    for category in allCategories 
    { 
     item(category) 
    } 
} 

それを使用して:

func iterateMyCategoriesItems(item:(_ category:Category) -> Void, _ completion:(() -> Void)? = nil) 
{ 
    for category in allCategories 
    { 
     item(category) 
    } 

    completion?() 
} 

しかし、今私はこのようなメソッドを使用しようとしている:

だから、私は間違って何をやっている

Missing argument for parameter 'item' in call.

コンパイラはエラーを示しますか?

答えて

1

あなたはすべきですあなたはこの呼び出しで末尾のクロージャを使用していることを識別することができる:

iterateMyCategoriesItems { (category) in 

    // doing something here with every category... 
} 

スウィフトコンパイラが、これは末尾の閉鎖であることを検出し、それが完了ハンドラである方法、の最後の引数に一致します。

これで、最初の引数と一致する他の引数が検索され続けます。誰も見つからないので、それは不平を言う。あなたもこのクリーナーを作るために、引数のラベルを削除することができます

iterateMyCategoriesItems(items: { (category) in 

    // doing something here with every category... 
}) 

はこれを修正するには、末尾の閉鎖を使用してあきらめ、適切に引数を渡す必要があります。次のように

2

あなたは、関数の末尾に{}を使用すると、コンパイラが自動的に(完成閉鎖に)あなたの関数の最後のパラメータに割り当てますので、それは項目のパラメータは、あなたのコール

から欠落していると考えて

あなたはそのようにそれを使用することができます。

iterateMyCategoriesItems (items:{ (category) in 

    // doing something here with every category... 
}) 

か、完了を持っているしたい場合は

iterateMyCategoriesItems (items: { (category) in 

    // doing something here with every category... 
}) { _ in 
    //do things when completed 
} 
1

Swift bookTrailing Closureについて説明します。

If you need to pass a closure expression to a function as the function’s final argument and the closure expression is long, it can be useful to write it as a trailing closure instead.

(太字スタイルが追加されます。)

それは明らかに最終としてターゲット引数を扱います。

最終的な引数がオプションであってもこのルールが適用されます。

//-> warning: closure parameter prior to parameters with default arguments will not be treated as a trailing closure 
func iterateMyCategoriesItems(item:(_ category:Category) -> Void, _ someOptionalIntParam: Int? = nil) 
{ 
    for category in allCategories 
    { 
     item(category) 
    } 
} 

//-> error: missing argument for parameter 'item' in call 
iterateMyCategoriesItems { (category) in 

    // doing something here with every category... 
} 

すでに述べたように、あなたの関数定義を保持する場合であるとして、他の回答で述べた:

func iterateMyCategoriesItems(item:(_ category:Category) -> Void, _ completion:(() -> Void)? = nil) 
{ 
    for category in allCategories 
    { 
     item(category) 
    } 

    completion?() 
} 

(これは別のトピックですが、あなたがしたい場合は、(Void)->Voidを避けるべきです引数なしのクロージャタイプを記述するにはthis threadを参照してください。

このようにする必要があります:

iterateMyCategoriesItems(item: { (category) in 

    // doing something here with every category... 
}) 

あなたは末尾のクロージャとして常にitem閉鎖を書きたい場合は、このようなあなたの関数定義を変更することができます:あなたが他の閉鎖前にcompletion閉鎖を置くことを好むしないことがあり、

func iterateMyCategoriesItems(completion:(() -> Void)? = nil, item:(_ category:Category) -> Void) 
{ 
    for category in allCategories 
    { 
     item(category) 
    } 

    completion?() 
} 

//Does not cause error 
iterateMyCategoriesItems { (category) in 

    // doing something here with every category... 
} 

しかし。

+0

この素敵な答えをありがとう! –

関連する問題