2015-02-08 75 views
7

我想創建一個函數來檢查user_id是否已經在我的數據庫中。Swift可以從異步無效返回塊返回值嗎?

class func checkIfUserExsits(uid:String) -> Bool { 
    userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value, withBlock: { (snapShot: FDataSnapshot!) -> Void in 
       if snapShot.value is NSNull { 
        return false 
       } else { 
        return true 
       } 
    }) 
} 

但是,observeSingleEventOfType是由第三方Firebase提供的API。它被定義爲返回Void

  • (void)observeSingleEventOfType:(FEventType)eventType withBlock:(void (^) (FDataSnapshot *snapshot))block

錯誤:Type 'Void' does not conform to protocol 'BooleanLiteralConvertible'

欣賞類型的任何幫助。


UPDATE

我試圖用不同的方式:

class func checkIfExist(uid: String) -> Bool { 
    var answer:Bool = false 
    var text:String = "not yet completed" 
    let queue = dispatch_group_create() 
    dispatch_group_enter(queue) 
     userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value, withBlock: { (snapShot: FDataSnapshot!) -> Void in 
       if snapShot.value is NSNull { 
        text = "This is a new user" 
        answer = false 
        dispatch_group_leave(queue) 
       } else { 
        text = "Found the user in Firebase" 
        answer = true 
        dispatch_group_leave(queue) 
       } 
     }) 
    dispatch_group_wait(queue, DISPATCH_TIME_FOREVER) 
    println(text) 
    return answer 
} 

不知怎的,它只是凍結在那裏。我知道這種方法現在可能是無關緊要的。但請幫助。

回答

14

你應該使用異步完成處理自己:

class func checkIfUserExists(uid: String, completionHandler: (Bool) ->()) { 
    userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value) { snapShot in 
     if snapShot.value is NSNull { 
      completionHandler(false) 
     } else { 
      completionHandler(true) 
     } 
    } 
} 

然後,您可以調用這個像這樣:

MyClass.checkIfUserExists(uid) { success in 
    // use success here 
} 

// but not here 

在修改後的問題,你展示給使用派遣組使這個異步方法表現同步。 (信號燈也經常用於同樣的目的。)

兩個問題:

  1. 如果他們派遣他們完成處理程序返回到主隊列這將死鎖(在許多情況下,圖書館將做到這一點爲了簡化我們的生活),因爲你巧合地阻止了他們嘗試使用的同一個線程。我不知道這是他們在這裏做的,但很可能。

    如果您想確認此事,請暫時刪除調度組,然後檢查NSThread.isMainThread並查看它是否在主線程中運行。

  2. 無論如何,你永遠不應該阻止主線程。他們提供了一個異步接口,因此您應該在調用它時使用異步模式。不要對抗異步模式,而應該擁抱它們。

+0

謝謝。我想知道是否有其他更不詳細的方式來做到這一點。我不喜歡我的項目全部嵌套在完整塊內的完整塊中。 – 2015-02-08 05:08:11

+0

非常感謝你Rob。我知道我可能以非常錯誤的方式做到這一點,但我仍然想嘗試一下。就像你說的那樣,我正在嘗試對這個功能進行異步處理。我不熟悉信號量。我試圖改用dispactch_group_wait。請參閱我的問題的更新。 – 2015-02-08 05:24:01

+3

如果他們將完成處理程序分發回主隊列(並且在很多情況下,庫會這樣做來簡化我們的生活),則會死鎖,阻塞主線程,等待庫將分發完成處理程序分發給你阻止的同一個線程。我不知道這是他們在這裏做的,但很可能。暫時刪除調度組,然後檢查'NSThread。isMainThread'如果你想確認。但是,我再一次強烈建議不要阻塞主線程,因爲你不太習慣使用閉包和異步模式。 – Rob 2015-02-08 05:30:33