我尝试使用 Manger 来管理我的职能。问题是功能代码更新并且在我将功能添加到我的经理时没有保存。我试着用这个例子来解释我的问题:
class QueueManager {
typealias FunctionType = () -> ()
private var functions = [(String, FunctionType)]()
func add(funcName: String, function: FunctionType) -> QueueManager {
functions.append(funcName, function)
return self
}
func runFirst() -> Bool {
guard functions.isEmpty == false else { return false }
functions.first!.1()
functions.removeFirst()
return true
}
}
然后我这样做:
let queueManager = QueueManger()
var value = 1
queueManager.add("simpleFunction"){
print(value)
}
value = 2
queueManager.add("simpleFunction"){
print(value)
}
queueManager.runFist()
queueManager.runFist()
结果是:
2 // Because value is 2 in both functions. But i added the function while value was 1??
2
但我想要结果:
1
2
我做错了什么?提前致谢!
编辑:非常简单的 Playground 示例:
import UIKit
var str = "1"
func go() {
print(str)
}
var array:[()->()] = []
array.append(go)
str = "2"
array.append(go)
array[0]()
array[1]()
// Output:
// 2
// 2
编辑 2: 我知道 2 2 是我的代码的正确输出。但我想将该功能保持在其创建状态。这有可能吗?
编辑 3: 感谢您所有的帮助。但我认为我未能充分解释我的问题以获得合适的答案。我想稍后用它的参数调用一个函数。我不想保留对参数值的引用。我只需要用这些参数值调用函数。
最佳答案
为了理解这里发生了什么,让我们一步步来看:
- 将 1 赋给值
- 将打印指令添加到
QueueManager
- 赋值2
- 将打印指令添加到
QueueManager
- 使用
runFirst()
运行函数
当您添加 print(value)
指令时,您将 value
作为引用类型传递。这在变量 functions
和 value
之间创建了一个强引用。因此,当您实际执行这些指令时,使用 runFirst()
它会使用当时存储在 value
中的值。
让我们使用这个例子来探索:
var value = 5
queueManager.add(funcName: "simpleFunction"){
print(value)
}
queueManager.add(funcName: "simpleFunction"){
print(value)
}
queueManager.runFirst()
queueManager.runFirst()
value = 10
// output is 5 5
在这种情况下,我们首先执行 runFirst()
然后更新值。因此输出为 5 5
。
TL;DR - 按引用传递导致函数打印变量 value
的当前值。
编辑:将数据绑定(bind)到 QueueManager
中的函数,这将确保数据的当前值(在函数定义期间)与函数关联。
class QueueManager {
typealias FunctionType = (Int) -> ()
private var functions = [(String, FunctionType, Int)]()
func add(funcName: String, function: @escaping FunctionType, data: Int) -> QueueManager
{
functions.append((funcName, function, data))
return self
}
func runFirst() -> Bool
{
guard functions.isEmpty == false else { return false }
functions.first!.1(functions.first!.2)
functions.removeFirst()
return true
}
}
let queueManager = QueueManager()
// define you function within this closure
let functionClosure: (Int) -> () = { (data) in
print(data)
}
var value = 1
queueManager.add(funcName: "simpleFunction", function: functionClosure, data: value)
value = 2
queueManager.add(funcName: "simpleFunction", function: functionClosure, data: value)
queueManager.runFirst()
queueManager.runFirst()
输出:
1
2
关于swift - 函数数组不会保留其创建时的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46682775/