代码之家  ›  专栏  ›  技术社区  ›  Jonas

函数数组不会阻止其值的创建

  •  0
  • Jonas  · 技术社区  · 8 年前

    我试着用经理管理我的职能。问题是,当我将功能添加到管理器时,功能代码会更新并且不会保存。我试着用这个例子来解释我的问题:

    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:

    3 回复  |  直到 8 年前
        1
  •  1
  •   NSAdi    8 年前

    为了了解这里发生了什么,让我们一步一步地看一下:

    1. 将1赋给值
    2. QueueManager
    3. 将打印指令添加到 队列管理器
    4. runFirst()

    当您添加 print(value) 你通过的指令 value functions 和 价值 . 因此,当您实际执行这些指令时,使用 runFirst() 然后使用存储在 价值

    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-通过引用传递使函数打印变量的当前值 价值 .

    编辑:将数据绑定到中的函数 ,这将确保数据的当前值(在函数定义期间)与函数相关联。

    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
  •   Ahmad F    8 年前

    根据您的代码,显然结果应该是:

    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() 之前 使命感 值=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公司

        3
  •  1
  •   Francesco Deliro    8 年前
    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”,(Function)),(“simpleFunction”,(Function))]

    1.

    [(“simpleFunction”,(Function))]

    2.

    推荐文章