我尝试用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
我做错了什么?提前谢谢!
编辑:非常简单的游乐场示例:
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: 感谢您所有的帮助。但我认为我没有足够的解释我的问题来得到合适的答案。我想稍后调用一个带有参数的函数。我不想保留对参数值的引用。我只需要用这些参数值调用函数。
答案 0 :(得分:1)
根据您的代码,显然结果应为:
2
2
因为您在编辑queueManager.runFirst()
value = 2
两次
此外,如果add
函数应包含functions.append((funcName, function))
,那么我假设其function
参数应为@escaping
,如下所示:
class QueueManager {
typealias FunctionType = () -> ()
private var functions = [(String, FunctionType)]()
func add(funcName: String, function: @escaping 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 = QueueManager()
var value = 1
queueManager.add(funcName: "simpleFunction") {
print(value)
}
queueManager.runFirst()
value = 2
queueManager.add(funcName: "simpleFunction"){
print(value)
}
queueManager.runFirst()
应该是:
1
2
因为 - 很简单 - 在
调用queueManager.runFirst()
之前我调用了value = 2
同样的问题适用于您的简单示例:
var str = "1"
func go() {
print(str)
}
var array:[()->()] = []
array.append(go)
array[0]()
str = "2"
array.append(go)
array[1]()
调用array.append(go)
不会导致执行go()
,您应该通过array[0]()
调用它;由于您尝试打印相同变量(str
)的值,因此always
将为其打印最新值。如果要为每个函数单独保存每个值,您应该 - 以某种方式 - 声明多个变量(value
或str
)。
答案 1 :(得分:1)
为了理解这里发生的事情,让我们一步一步看看:
QueueManager
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 - Pass By Reference导致函数打印变量value
的当前值。
编辑:将数据绑定到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
答案 2 :(得分:1)
req.body.MediaUrl{N}
添加第一个simpleFunction后,您必须更新您的值。
游乐场输出:
[(" simpleFunction",(Function)),(" simpleFunction",(Function))]
1
[(" simpleFunction",(Function))]
2