2017-02-06 8 views
0

私はSwiftクラスTestを次の初期化子で使用しています。Swiftの変数割り当てに失敗しました

import Foundation 

class Test { 
    var x: Int 

    var response: [String: AnyObject] 

    init(_ x: Int) { 
     self.x = x 

     self.response = [String: AnyObject]() 

     self.y(x) 
    } 
} 

Testの中には、以下の方法もあります。呼び出しy

func y(_ x: Int) { 
    // This is a task with a completion handler of type (_, _, _) -> Void 
    let ... = ...(with: ..., completionHandler: {() in 
     do { 
      // The type of z is [String: AnyObject] 
      let z = ... 
      self.response = z 
     } catch { 
      return 
     } 
    }) 

self.responsezを再割り当てすることになったが、self.responseは永続的に空の辞書です。

何か不足していますか?

+0

ときあなたのcompletionHandlerはasyncと呼ばれ、 'self'はまだ存在しますか? また、completionHandlerは自動で 'エスケープする 'ので、self.responseをどこでチェックしましたか? – antonio081014

+0

関数yは補完ハンドラが終了するのを待っていません。すぐに戻り、Test.init()はself.responseが設定される前に完了します。また、自己への弱い参照を補完ハンドラに渡す必要があります。 – onnoweb

+0

@onnoweb 'completionHandler:{()in'を' completionHandler:{[weak self]()in'と 'self.response = z'を' self?.response = z'に変更すると、 'self.response'まだ空です。 – Angelo

答えて

0

これは何かのように思えますが、再考したいかもしれませんが(同様の質問でこの素敵な答えを指摘しておきます:https://stackoverflow.com/a/12797624/2617369)、私は補完をあなたのy方法と、このようなディスパッチグループと:

(私は2.3でお見せするために、以前のバージョンのIDEを持っていないが、それは違うあまりすべきではないので、これは3 SWIFTです):

class Test { 
    var x: Int 

var response: [String: Any] 

init(_ x: Int) { 
    self.x = x 

    self.response = [String: Any]() 

    let group = DispatchGroup() 
    group.enter() 
    self.y(x) { (result) in 
     self.response = result 
     group.leave() 
    } 

    group.wait() 
} 

func y(_ x: Int, completion:@escaping (([String:Any])->())) { 
    // This is a task with a completion handler of type (_, _, _) -> Void 
    let ... = ...(with: ..., completionHandler: {() in 
     do { 
     // The type of z is [String: Any] 
      let z = ... 
      completion(z); 
     } catch { 
     return 
     } 
    } 
} 
+0

これは私の質問に答え、私の問題を解決しました。本当にありがとう! – Angelo

関連する問題