2017-08-25 348 views
-1

我有一個計算的屬性,預計將返回一個對象或零,如果它失敗。迅速計算的財產返回值

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行上解包可選值錯誤。它看起來像代碼跳過我的關閉功能,並直接返回。

感謝

+3

也許請求是* asynchronous *? –

回答

0

我有一個預期,如果它不能返回一個對象或零一個計算性能。

那麼你或許應該把它定義爲:

var findRequest: Book? { 
    // ... 

(注意後Book 「?」)

此外,像馬丁在評論中提到,你的計算機屬性的getter是應該馬上返回一個值,但是你正在做一個異步調用來檢索值。在完成處理程序被調用之前,getter本身立即返回。訪問該屬性的一側無法獲取該API返回的實際值。

+0

謝謝 - 在這一點上函數調用會更好,還是我仍然可以使用CP? – user7684436

+0

是的,但接受完成處理程序的函數。在閉包被回調之前,你不能做任何事情,這就是異步調用的重點。 –

2

您的實施有幾個問題。首先,如果可能的值爲nil,則不應將foundRequest定義爲隱式解包的可選項。其次,您將異步函數API.requestBook的完成處理程序之外的值返回,因此您在返回foundRequest之前可能會得到一個值,因此您將返回默認值nil,這將由於隱式解包而強制解包可選的聲明,因此錯誤。

此外,您不應該在計算屬性的getter內部發出異步請求,因爲計算的屬性應該立即返回一個值。

您應完全更改您的實現,以使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) 
      } 
     } 
} 

您可以調用該函數是這樣的:

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

您可能需要根據什麼輸入參數book需要的類型從URLRequest改變bookRequest類型。

+0

謝謝 - 不知道CP's會等到關閉完成。會重構。 – user7684436