【问题标题】:Swift Closure ExpressionSwift 闭包表达式
【发布时间】:2017-03-31 04:21:39
【问题描述】:

我必须将一些名称下载到一个数组中,但我不知道将下载多少个名称。只有在下载完所有名称后,我才需要运行自定义函数。

我使用闭包来调用自定义函数,但是一旦下载了第一个名称,我的自定义函数会立即被调用,然后下载第二个名称,然后再次调用自定义函数等等。

我需要仅在将所有名称下载到数组后调用自定义函数,而不是在下载每个名称后调用。我在哪里做错了什么?

这就是我得到的:

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()
      }
    }
}

【问题讨论】:

  • == true 无需检查Bool。只需直接使用Bool。另外,避免命名nameArray 之类的东西。就叫它names。复数意味着它是一个像数组一样的集合。
  • @Alexander Momchliov 感谢您的建议!

标签: arrays swift callback closures


【解决方案1】:

addAllNamesToArrayThenRunClosure 实际上只添加一个名称,每个名称调用一次。如果你在那里调用你的完成处理程序,它将被调用......每个名称一次。您需要重新设计它,以便在添加所有名称后调用闭包。

我会这样做:

//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")
    }
}

【讨论】:

  • 我想你想多了。根据您的描述,您不需要完成处理程序或任何此类。 “随机名称”的来源是什么?
  • 那为什么不只是一个数组呢?
  • globalNames += photos.flatMap{ $0.metadata?.dowbloadUrl()?.absoluteString }
  • 然后在下一行做任何你需要做的事情。不需要完成处理程序
  • 你为什么用循环生成字符串数组,而不仅仅是地图/平面图?
【解决方案2】:

我建议在addAllNamesToArrayThenRunClosure 方法中添加for 循环。然后,您可以在添加完所有名称后调用完成处理程序。

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

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

然后,从完成处理程序中调用您的自定义函数,如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 2013-12-14
    • 2013-09-21
    • 2015-05-09
    相关资源
    最近更新 更多