2017-10-11 3 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 

何が間違っていますか?前もって感謝します!

EDIT:非常に簡単な遊び場例:

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 

EDIT 2: 私は2 2は、私のコードのための右の出力であることを知っています。しかし、私は創造の状態で機能を保持したい。これは何とか可能ですか?

編集3: ご協力いただきありがとうございます。しかし、私は答えを納得させるのに十分なほど問題を説明できないと思う。私は後でそのパラメータで関数を呼びたいと思う。私はパラメータ値への参照を保持したくありません。私はこれらのパラメータ値で関数を呼び出す必要があります。あなたのコードに基づいて

答えて

1

  1. 割り当てる1値へ
  2. 値に割り当て2 QueueManager
  3. に印刷指示を追加します。 QueueManager
  4. に関数を実行します。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 - Pass By Referenceは、変数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() 

OUTPUT:

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 

私は同じ問題があなたの簡単な例にも適用することがvalue = 2

を呼び出すqueueManager.runFirst()と呼ば-simply-理由:

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"、(機能))]

[( "simpleFunction"、(機能) )]

+0

あなたの答えをありがとう。残念ながら値は他の場所で変更されます。私は関数でそれを更新することはできません。関数が追加された時から値の値を保持するだけでいいです –

関連する問題