2017-09-15 90 views
0

我的目標是異步執行資源佔用較大的操作,並確保在返回對象之前它已完成。確保異步操作中的循環在返回前完成

這是結構:

func modifyGadgets() -> [Gadget] { 

    var gadgetsToModify = [Gadget]() //this is already populated elsewhere 

    DispatchQueue.global(qos: .userInitiated).async { 
     //Do something to the original gadgets 
     for gadget in gadgetsToModify { 
      modifyThisGadget(gadget) 
     } 

     DispatchQueue.main.async { 
      return gadgetsToModify //I get a warning here saying gadgetsToModify is unused 
     } 

    } 
} 

除了警告,我還沒有得到任何的Gadget項背。

我應該如何構造這個以便我能夠在完成後返回物品?

謝謝。

回答

3

您應該使用完成處理程序爲此。

func modifyGadgets(_ callback: @escaping ([Gadget]) ->()) { 
    var gadgetsToModify = [Gadget]() 

    DispatchQueue.global(qos: .userInitiated).async { 
     for gadget in gadgetsToModify { 
      modifyThisGadget(gadget) 
     } 

     DispatchQueue.main.async { 
      callback(gadgetsToModify) 
     } 
    } 
} 

你可以用這種方式:

modifyGadgets { gadgets in 
    print(gadgets) 
} 
+1

您需要在完成處理'@ escaping'。 –

+0

謝謝你們兩位。這非常有幫助 – daspianist

2

如果操作是異步的,你將無法以這種方式返回值。你想要做的,而不是什麼是採取封閉的完成處理程序:

func modifyGadgets(completionHandler: @escaping ([Gadget]) ->()) { 
    let gadgets = ... 

    DispatchQueue.global(qos: .userInitiated).async { 
     //Do something to the original gadgets 
     for eachGadget in gadgets { 
      modifyThisGadget(eachGadget) 
     } 

     completionHandler(gadgets) 
    } 
} 

然後,你可以這樣調用:

modifyGadgets { gadgets in 
    // do something with gadgets 
}