函数数组不会保留其创建时的值
Array of functions don't keep their values from their creation
我尝试使用 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:
感谢您所有的帮助。但我认为我未能充分解释我的问题以获得合适的答案。我想稍后用它的参数调用一个函数。我不想保留对参数值的引用。我只需要用这些参数值调用函数。
根据你的代码,显然结果应该是:
2
2
因为您在编辑 value = 2
之后 调用了 queueManager.runFirst()
两次
此外,如果 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
因为 - 简单 - 我在
调用 value = 2
之前调用了 queueManager.runFirst()
同样的问题也适用于您的简单示例:
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]()
调用;由于您正在尝试打印 same 变量 (str
) 的值,它将 always
打印它的最新值。如果你想为每个函数分别保存每个值,你应该 - 以某种方式 - 声明多个变量(value
或 str
)。
为了了解这里发生了什么,让我们一步一步地看一下:
- 将 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
.
的当前值
编辑:将数据绑定到 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
import UIKit
var str = "Hello, playground"
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 }
print(functions)
functions.first!.1()
functions.removeFirst()
return true
}
}
var value = 1
let queueManager = QueueManager()
func simpleFunction(_ value: AnyObject){
print(value)
}
queueManager.add(funcName: "simpleFunction"){
simpleFunction(value as AnyObject)
}
queueManager.add(funcName: "simpleFunction"){
value = 2
simpleFunction(value as AnyObject)
}
queueManager.runFirst()
queueManager.runFirst()
您必须在添加第一个 simpleFunction 后更新您的值。
游乐场输出:
[("simpleFunction", (函数)), ("simpleFunction", (函数))]
1
[("simpleFunction", (函数))]
2
我尝试使用 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: 感谢您所有的帮助。但我认为我未能充分解释我的问题以获得合适的答案。我想稍后用它的参数调用一个函数。我不想保留对参数值的引用。我只需要用这些参数值调用函数。
根据你的代码,显然结果应该是:
2
2
因为您在编辑 value = 2
queueManager.runFirst()
两次
此外,如果 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
因为 - 简单 - 我在
调用value = 2
之前调用了 queueManager.runFirst()
同样的问题也适用于您的简单示例:
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]()
调用;由于您正在尝试打印 same 变量 (str
) 的值,它将 always
打印它的最新值。如果你想为每个函数分别保存每个值,你应该 - 以某种方式 - 声明多个变量(value
或 str
)。
为了了解这里发生了什么,让我们一步一步地看一下:
- 将 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
.
编辑:将数据绑定到 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
import UIKit
var str = "Hello, playground"
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 }
print(functions)
functions.first!.1()
functions.removeFirst()
return true
}
}
var value = 1
let queueManager = QueueManager()
func simpleFunction(_ value: AnyObject){
print(value)
}
queueManager.add(funcName: "simpleFunction"){
simpleFunction(value as AnyObject)
}
queueManager.add(funcName: "simpleFunction"){
value = 2
simpleFunction(value as AnyObject)
}
queueManager.runFirst()
queueManager.runFirst()
您必须在添加第一个 simpleFunction 后更新您的值。
游乐场输出:
[("simpleFunction", (函数)), ("simpleFunction", (函数))]
1
[("simpleFunction", (函数))]
2