2017-08-25 2 views
-1

オブジェクトを返すと予想される計算されたプロパティまたは失敗した場合はnilがあります。スウィフト計算されたプロパティの戻り値

var findRequest: Book { 
    get { 
     var foundRequest: Book! 
     API.requestBook(book: bookRequest) { book in 
      if book != nil { 
       foundRequest = book! 
      } else { 
       print("Could not find book") 
       foundRequest = nil 
      } 
     } 
     return foundRequest 
    } 
} 

私は、コードを実行すると、戻りfoundRequestライン上の任意の値の誤差をアンラップしながら、私が予期せずnilを取得します。コードが私のクロージャー機能をスキップして、まっすぐに戻ります。

おかげ

+3

おそらくリクエストは*非同期ですか? –

答えて

0

私はそれが失敗した場合、オブジェクトはnilを返すことが期待されている計算された性質を持っています。マーティンはコメントで述べたように

また、あなたの計算されたプロパティのゲッターがある( "?" Book後に注意してください)

var findRequest: Book? { 
    // ... 

あなたはおそらくとしてそれを定義する必要があります値をすぐに返すはずですが、値を取得するための非同期呼び出しのように見えます。完了ハンドラが呼び出される前に、ゲッター自体がすぐに戻ります。プロパティにアクセスする側がAPIによって返される実際の値を取得する方法はありません。

+0

ありがとうございます - この時点で関数呼び出しがうまくいくか、それとも私はまだCPを使用できますか? – user7684436

+0

はい、ただし、完了ハンドラを受け付ける関数です。クロージャが呼び出されるまでは何もできません。それは非同期呼び出しの全体のポイントです。 –

2

実装にはいくつかの問題があります。まず、nilの可能性がある場合は、暗黙的にアンラップされたオプションとしてfoundRequestを定義しないでください。第2に、非同期関数API.requestBookの補完ハンドラの外に値を戻しているので、foundRequestが値を取得する前に戻っているので、暗黙的にラップ解除されたためにアンラップされるnilのデフォルト値を返していますオプションの宣言、したがってエラー。

また、計算されたプロパティはすぐに値を返すことになっているので、計算されたプロパティのゲッター内で非同期の要求を行うべきではありません。

findRequestが完了ハンドラ内でタイプBookの値を返す関数になるように実装を完全に変更する必要があります。

func findRequest(bookRequest: URLRequest, completion: @escaping (Book?->Void)){ 
     API.requestBook(book: bookRequest) { book in 
      if let book = book { 
       completion(book) 
      } else { 
       print("Could not find book") 
       completion(nil) 
      } 
     } 
} 

あなたはこのように関数を呼び出すことができます:あなたが入力パラメータbookの種類があることを必要とするものに応じて、URLRequestからbookRequestの種類を変更する必要がある場合があります

findRequest(bookRequest: yourRequest, completion: { book in 
    if let book = book { 
     //use the returned value 
    } else { 
     print("Book not found") 
    } 
}) 

+0

ありがとうございました - 閉鎖が完了するまで、CPは待機しませんでした。リファクタリングします。 – user7684436

関連する問題