2017-10-11 14 views
0

관리자와 함께 내 기능을 관리하려고합니다. 문제는 기능 코드가 업데이트되어 관리자에게 기능을 추가하는 순간 저장되지 않는다는 것입니다.함수 배열이 생성시 값을 유지하지 않습니다.

let queueManager = QueueManger() 

var value = 1 

queueManager.add("simpleFunction"){ 
    print(value) 
} 

value = 2 

queueManager.add("simpleFunction"){ 
    print(value) 
} 

queueManager.runFist() 
queueManager.runFist() 

그리고 결과입니다 : 그럼이 할

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 
    } 
} 

:이 예제를 내 문제를 설명하려고

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 내 코드에 적합한 출력 것을 알고있다. 그러나 저는 그 기능을 창조 상태로 유지하고 싶습니다. 어떻게 든 가능합니까?

편집 3 : 도움 주셔서 감사합니다. 그러나 나는 내 문제를 충분히 설명해 줄 수는 없다고 생각한다. 나중에 매개 변수가있는 함수를 호출하려고합니다. 필자는 매개 변수 값에 대한 참조를 유지하고 싶지 않습니다. 그 매개 변수 값으로 함수를 호출하면됩니다. 코드를 기반으로

답변

1

을 단계별로 살펴 걸릴 수 있습니다 :

    값에
  1. 지정 1
  2. 값에 할당이 QueueManager
  3. 에 인쇄 명령 추가를
  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 - 참조로 전달 기능은 변수 value의 현재 값을 인쇄합니다.

EDIT : 데이터를 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 
+0

함수를 생성 상태로 유지할 수 있습니까? 나는 그것을 나중에 추가했을 때의 가치와 함께 나중에 전화하고 싶다. –

+0

물론, 당신이해야 할 일은 가치있게 전달하는 것입니다. 나는 이것을 달성하는 가장 간단한 방법으로 대답을 업데이트했다. – NSAdi

+0

답변 해 주셔서 감사합니다! 그러나 그것은 정말 더러운 해결책처럼 보입니다. 이것으로 100 개가 넘는 기능을 관리합니다.함수의 각각에 대해 새로운 변수를 만들면 나는 1000 개가 넘는 새로운 값을 생성합니다. 이것을 보관할 다른 방법이 있어야합니다. 다른 언어에서도 가능합니다. –

1

, 분명히 결과가 있어야한다 :

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 

같은 문제가 귀하의 간단한 예에 적용 가능하다 내가 전에 queueManager.runFirst()라고 -simply-이 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)를 선언해야합니다. 여기에 무슨 이해하기 위해

+0

나는 어디에 문제가 있는지 알고있다. 하지만 나중에 함수를 호출하고 싶습니다. 하지만 제 질문은 : 어떻게 첫 번째 함수에서 첫 번째 값을 유지할 수 있습니까? 나는 생성 시간 값으로 함수를 저장하고 싶다. 그것을 추가 할 때 값의 상태를 유지해야합니다. 네가 한 위치에서 그냥 부르면, 매니저는 완전히 쓸모가 없을거야. –

1
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"(기능))]

+0

답변 해 주셔서 감사합니다. 슬프게도 다른 곳에서는 값이 변경됩니다. 함수에서 업데이트 할 수 없습니다. 함수가 추가 된 시간부터 값의 가치를 유지하기 만하면됩니다. –