2016-11-16 11 views
0

いくつかの名前を配列にダウンロードする必要がありますが、ダウンロードする名前の数は正確にはわかりません。すべての名前がダウンロードされた後で、実行するカスタム関数が必要です。Swift Closure Expression

私はカスタム関数を呼び出すためにクロージャを使用しますが何が起こるかは、最初の名前をダウンロードしたら、私のカスタム関数は、それから2番目の名前がダウンロードされ、すぐに呼ばなっている、カスタム関数が

など再び呼ばれています

名前をダウンロードした後ではなく、すべての名前が配列にダウンロードされた後に呼び出されるようにするには、カスタム関数が必要です。私はどこで何か間違っているのですか?

これは私が取得していますものです:これは私が欲しいものである

Mable 
This should only print once not three times 
Marlene 
This should only print once not three times 
Moses 
This should only print once not three times 

Mable 
Marlene 
Moses 
This should only print once not three times 

可能ならば、私は、問題は内部で解決されたい:addAllNamesToArrayThenRunClosure

コード:

//There actually can be 1 or 100 names but I just used 3 for the example 
var randomNames = ["Mable", "Marlene", "Moses"] 
var nameArray = [String]() 

func addAllNamesToArrayThenRunClosure(name: String, completionHandler: (success:Bool)->()){ 
    nameArray.append(name) 
    print(name) 

    let flag = true 
    completionHandler(success:flag) 
} 

func customFunction(){ 
    print("This should only print once not three times") 
} 

for name in randomNames{ 
    addAllNamesToArrayThenRunClosure(name){ 

     //Shouldn't this run only after the array is filled? 
     (success) in 
     if success == true{ 
      customFunction() 
     } 
    } 
} 
+0

。 'Bool'を直接使用してください。また、 'nameArray'のような名前を付けないでください。単にそれを '名前'と呼んでください。複数のことは、配列のようなコレクションであることを意味します。 – Alexander

+0

@Alexander Momchliovアドバイスありがとう! –

答えて

1

addAllNamesToArrayThenRunClosureは実際には単一の名前を追加するだけで、名前ごとに1回呼びます。そこで補完ハンドラを呼び出すと、名前ごとに1回呼び出されます。これを再設計して、すべての名前が追加された後にクロージャが呼び出されるようにする必要があります。ここで

は、私はそれを行うだろう方法は次のとおりです。

//There actually can be 1 or 100 names but I just used 3 for the example 
var randomNames = ["Mable", "Marlene", "Moses"] 
var globalNames = [String]() 

func add(names: [String], completionHandler: (_ success: Bool) -> Void) { 
    globalNames.append(contentsOf: names) 

    completionHandler(true) 
} 

add(names: randomNames) { success in 
    if success { 
     print("Finished") 
    } 
} 
+0

私はあなたがこれを考えていると思います。あなたが記述したことで、補完ハンドラ、またはそのいずれかが必要ありません。 「ランダムな名前」のソースは何ですか? – Alexander

+0

それでは、なぜ単なる配列ではありませんか? – Alexander

+0

'globalNames + = photos.flatMap {$ 0.metadata?.dowbloadUrl()?. absoluteString}' – Alexander

1

私はaddAllNamesToArrayThenRunClosure方法でforループを追加することをお勧めします。次に、すべての名前が追加された後で補完ハンドラを呼び出すことができます。その後

var randomNames = ["Mable", "Marlene", "Moses"] 
var nameArray = [String]() 

func addAllNamesToArrayThenRunClosure(completionHandler: (success: Bool) ->()) { 
    for name in randomNames { 
     nameArray.append(name) 
    } 
    completionHandler(true) 
} 

、そのように完了ハンドラからカスタム関数を呼び出す: `==` true`にBool`を確認するための必要はありません

addAllNamesToArrayThenRunClosure() { success in 
    self.customFunction() 
}