2017-06-02 3 views
2

補完ブロック内で関数パラメーターに値を代入しようとするとエラーが発生します。エスケープクロージャーでは、値 '。Swift 3でクロージャー内のinoutパラメーターに値を代入する

どうすればこの問題を解決できますか?どんなヒントも大歓迎です!

func fetchCurrentUser(user: inout User?) { 
    self.fetchUser(withId: AuthProvider.sharedInstance.currentUserId(), completionHandler: { 
     fetchedUser in 
     guard let newUser = fetchedUser else { return } 
     user = newUser // error Here 
    }) 
} 
+0

を使用することができます。また、[この答え]を見つけることができ(https://stackoverflow.com/a/ 39572470/709202)が役に立ちました。 –

答えて

1

私はこのリファクタリングを提案:

func fetchCurrentUser(callback: @escaping (User) ->()) { 
    self.fetchUser(withId: AuthProvider.sharedInstance.currentUserId(), completionHandler: { 
     fetchedUser in 
     guard let newUser = fetchedUser else { return } 
     callback(newUser) 
    }) 
} 

か、fetchCurrentUserは同期になりたい場合は、セマフォ

+1

私はクロージャのパラメータをオプションにすることをお勧めします。 'func fetchCurrentUser(コールバック:@escaping(User?) - > Void){...}'、失敗した場合は 'nil'を呼び出して終了します。エラーがあったかどうかを発信者が知りたがるようにしてください。同期提案は、ほとんど常に悪い考えであり、通常、深く根付いた設計上の瑕疵については、コードの匂いがかかります。 – Rob

1

補完ハンドラを使用するため、これは機能しません。 self.fetchUserは直ちに戻り、バックグラウンド作業(ネットワーク要求である可能性が高い)が完了すると完了ハンドラが実行されます。

あなたの関数fetchCurrentUserは、self.fetchUserを呼び出して返します。したがって、完了ブロックが実行される前に戻ります。

エスケープクロージャでは、inoutパラメータを使用することはできません(これはエラーメッセージにも示されます)。エスケープクロージャは、関数の後に実行されるクロージャです。

補完ハンドラを使用するか、関数を変更して補完ハンドラが実行されるのを待ってからfetchCurrentUser関数を終了することもできます。しかし、2番目のアプローチでは、これによって関数の呼び出し元が他のものを実行することもブロックされることに注意してください。

+0

あなたの洞察をいただきありがとうございます。私はfetchedUserがアクセス可能な時間を考え出し、inoutのparam(ユーザー)はその値を割り当てられます。 –

関連する問題