2017-09-15 115 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 
}