2015-11-05 79 views
0

我試圖將我的應用程序移到MVC,我有一個Parse查詢,我已經移到我的模型類中的函數,該函數返回一個Bool。Swift函數不會很快返回

當我按下我的ViewController中的按鈕時,應該運行模型函數'parseQuery',返回一個布爾值,然後我需要使用該布爾值來繼續。此時,if語句在函數完成之前執行,因此它總是檢測到false。

如何確保函數完成後if語句完成?

@IBAction func showAllExpiredUsers(sender: AnyObject) { 

    var success = searchResults.parseQuery() 

    if success { 
     print("true") 
    } else { 
     print("false") 
    } 
    //I have also tried: 

    searchResults.parseQuery() 

    if searchResults.parseQuery() { 
     print("true") 
    } else { 
     print("false") 
    } 
+0

你有沒有試過把這個函數放到'viewDidLoad'? – Korpel

+0

是parseQuery()你創建的函數嗎?這不是在解析API – Steve

+0

讓我猜 - 功能是異步? – luk2302

回答

0

您有幾個選項,但問題是由於異步調用。

解析是否顯示相同的函數,並帶有完成塊?

如果是,則將Bool的處理放置在Completlion塊中,這將在異步任務完成時調用。

如果沒有,我懷疑,你可以創建一個NSOperationQueue,以1:1的maxConcurrency(所以它是串行)與

func addOperationWithBlock(_ block:() -> Void)

這就是所謂的調度呼叫到隊列隊列。您需要全局存儲成功布爾值,以便您可以在第二個排隊塊操作中訪問它,以檢查成功狀態。

更新:

我還沒有使用解析,但檢查findObjectsInBackgroundWithBlock(https://parse.com/docs/ios/guide#queries)的文檔需要完成塊,你可以處理結果,更新您的布爾。

林不知道你在做什麼。您不需要具有查詢的成功狀態。你可以檢查

if (!error) { 
    // do stuff 
} else { 
    //error occured - print("error \(error.localizedDescription)" 
} 

檢查示例。

你需要了解的是線程。異步任務提供了一個完成塊,因爲它的異步,它被分派到另一個線程進行處理。我不確定你知道多少線程,但有一個叫做線程池的東西。此線程池由隊列訪問。線程池由OS管理,並確保可用線程可供需要完成工作的隊列使用。當用戶與應用交互時,這個(以及所有的UI工作)在主線程上完成。

因此,無論何時某些處理將干擾可能的交互或UI更新,都應該在主線程之外調度(Grand Central Dispatch)或排隊(NSOperationQueue,構建於GCD之上)。

無論如何,這就是爲什麼findObjectsInBackgroundWithBlock調用派發的主線程,因爲否則它會阻止主線程,直到它完成,破壞用戶的體驗。另外,如果主線程被阻塞超過1分鐘(最後一次檢查),操作系統的監視程序將會終止進程。

所以是,分配一個布爾值到塊的返回,將得到該函數的返回,該操作在完成塊完成之前發生。完成塊是你在函數完成後編寫一些東西的地方。因此,queury被派發到另一個線程並開始處理,發送這個工作以供處理的線程繼續執行其餘的部分。所以直接檢查布爾值,不會工作,因爲另一個線程不完整。即使其他線程及時完成,將後臺線程與主線程連接起來是什麼?

這是塊(功能指針)的美麗,它是一個更清潔和優化,並保持代碼緊湊。舊的方式,仍然是用於一些較舊的框架,委託,它將調用代碼與回調分離並添加委託依賴。積木很漂亮。

它也很重要,要注意完成塊不總是在主線程上調用。在許多情況下,由您決定將工作分派回主線程,以處理完成塊中可用對象需要完成的任何UI工作。

+0

很好的回覆,謝謝。你能解釋'揭露同樣的功能'是什麼意思嗎?我的函數是一個常規的findObjectsInBackgroundWithBlock,我試圖從完成塊內更新Bool,但是這發生在時間之後。我一直在addOperationWithBlock,希望這會有所幫助,但它不工作 –

+0

@BenSullivan - 我已經更新了答案 – jarryd

+0

我真的很感謝詳細的迴應,它使事情變得更加清晰。這聽起來像我可能需要保持我的查詢在控制器而不是模型。我需要返回布爾的原因實際上是說如果真的,然後顯示警報,如果錯誤顯示錯誤警報,問題是我無法成功地從模型中調用警報,我假設這是不可能的,但如果它是然後讓我知道。再次感謝。 –

0

查詢可能需要一些時間來運行,應該在後臺線程有一個回調函數來運行,當它完成了處理響應。

看看Documentation

具體看query.findObjectsInBackgroundWithBlock代碼:

var query = PFQuery(className:"GameScore") 
query.whereKey("playerName", equalTo:"Sean Plott") 
query.findObjectsInBackgroundWithBlock { 
    (objects: [PFObject]?, error: NSError?) -> Void in 

    if error == nil { 
    // The find succeeded. 
    print("Successfully retrieved \(objects!.count) scores.") 
    // Do something with the found objects 
    if let objects = objects as? [PFObject] { 
     for object in objects { 
     print(object.objectId) 
     } 
    } 
    } else { 
    // Log details of the failure 
    print("Error: \(error!) \(error!.userInfo!)") 
    } 
} 

上面的代碼將執行查詢,並運行在塊中的代碼,當它從解析得到的結果。這被稱爲異步任務,更多信息請查看this guide

+0

謝謝,這是我目前正在做的,但是這個塊沒有儘快完成。 –