【问题标题】:How to use closures in a for loop in swift?如何在 swift 的 for 循环中使用闭包?
【发布时间】:2015-03-06 02:16:44
【问题描述】:

我在 swift 中有一系列按钮。每个按钮都有一个闭合。我正在尝试在 for 循环中使用 i 作为每个闭包中的值。

 for(var i = 0; i < 30; i++){
            chapterOnePanel.chapters[i].onClickListener = {
                (x:Float32, y:Float32) in
                let r = i + 1;
                self.ChapterLoad = "1";
                self.LevelLoad = String(r);
                self.loadLevel = true;
            }
        }

如您所见,我在循环中使用 ii+1 存储在 r 中,然后存储 r LevelLoad 变量中。但是这不起作用,应用程序崩溃并且 LevelLoad 被标记为 nil。我知道在 Java 中你必须将 r 变量声明为 final 才能工作。有没有办法在 Swift 中做到这一点?

下面是 GoZoner 提供的答案。

     for(var i = 0; i < 30; i++){
              let r = i + 1;                    
              chapterOnePanel.chapters[i].onClickListener = {
                        (x:Float32, y:Float32) in

                        self.ChapterLoad = "1";
                        self.LevelLoad = String(r);
                        self.loadLevel = true;
                    }
                }

【问题讨论】:

  • “这不起作用”是毫无意义的fladdoodle。应用程序何时崩溃?在哪条线上?用什么信息?
  • 如在变量中标记为nil
  • 虽然回答了一点,这显然是一个问题:不。 Swift 中没有 final 之类的东西。匿名类,比如 Java,与真正的闭包非常不同。
  • @NJGUY 哪个变量是nil?你实例化了吗?例如,您是否实例化了chapterOnePanel 引用的对象?假设你这样做了,你是否已经实例化了 chapters 的数组?

标签: ios swift


【解决方案1】:

这是一个错误:

var data : [(Int) -> ()] = []

for (var i = 0; i < 5; i++) {
  data.append { (j:Int) in
    println (j + i)
  }
}

 9> data[0](10)  
15 // should be 10

[编辑:实际上不是错误;这就是某些语言的方式,Swift 也是如此。我描述的“变通”是您如何处理这个问题(不仅仅是“变通”)]

变量i 在闭包的主体中没有被修改,因此在创建闭包时它必须被“复制”(参见“Capturing Values”)。相反,显然,编译器看到 i 是可修改的,尽管在闭包之外,并且错误地得出需要“引用”的结论。

要解决此问题,请将引用移动到闭包之外的错误捕获的i

Welcome to Swift version 1.2. Type :help for assistance.
  1> var data : [(Int) -> ()] = [] 
  2.  
  3. for (var i = 0; i < 5; i++) { 
  4.   let r = i
  5.   data.append { (j:Int) in 
  6.     println (j + r)
  7.   } 
  8. } 
data: [Int -> ()] = 5 values {
  [0] = ($__lldb_expr2`partial apply forwarder for reabstraction thunk helper from @callee_owned (@unowned Swift.Int) -> (@unowned ()) to @callee_owned (@in Swift.Int) -> (@out ()) at repl1.swift)
  ...
  [4] = ($__lldb_expr2`partial apply forwarder for reabstraction thunk helper from @callee_owned (@unowned Swift.Int) -> (@unowned ()) to @callee_owned (@in Swift.Int) -> (@out ()) at repl1.swift)
}
  9> data[0](10)
10
 10> data[4](10)
14

【讨论】:

  • 我看到了你描述的同样的行为,发布了一个答案,只是注意到当我用 OP 的代码尝试它时,它在这种情况下复制它很好(所以我删除了我的回答,因为在这种情况下它似乎不是问题)。此外,OP 现在引用了一些关于 nil 变量的问题,这让我认为这里有一个更简单的问题,即他可能根本无法初始化 chapterOnePanelchapters(或类似的东西)那个)。
猜你喜欢
  • 2019-02-13
  • 2011-01-12
  • 2017-08-05
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2018-07-01
  • 1970-01-01
相关资源
最近更新 更多