swift - 函数数组不会保留其创建时的值

标签 swift xcode function chain

我尝试使用 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. 将 1 赋给值
  2. 将打印指令添加到QueueManager
  3. 赋值2
  4. 将打印指令添加到QueueManager
  5. 使用 runFirst() 运行函数

当您添加 print(value) 指令时,您将 value 作为引用类型传递。这在变量 functionsvalue 之间创建了一个强引用。因此,当您实际执行这些指令时,使用 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/

相关文章:

ios - 如何检查 iPhone 是否连接了 360 度相机?

ios - API 调用阻塞 UI 线程 Swift

xcode - IOS:弹出位置

ios - TableView 单元格在滚动时消失

ios - 通过 simctl 安装 WatchKit 应用程序

传递函数参数时的 C++ 执行顺序

php - 什么是编写 php mysql 函数的最佳方法?

ios - 链接器命令代码失败并退出 1

swift - 缺少 LinuxMain.swift 文件

php - 从按钮调用 PHP 函数以从表中删除行