Parameters 在Swift中,如何在GCD主线程上调用带参数的方法?

Parameters 在Swift中,如何在GCD主线程上调用带参数的方法?,parameters,swift,grand-central-dispatch,Parameters,Swift,Grand Central Dispatch,在我的应用程序中,我有一个函数,可以创建NSRURLSession并使用 sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error) 在该任务的完成块中,我需要进行一些计算,将UIImage添加到调用viewcontroller。我有一个函数叫做 func displayQRCode(receiveAddr, withAmountInBTC:amountBTC) 这将执行UIImage添加计算。如果我尝试

在我的应用程序中,我有一个函数,可以创建NSRURLSession并使用

sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)
在该任务的完成块中,我需要进行一些计算,将UIImage添加到调用viewcontroller。我有一个函数叫做

func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
这将执行UIImage添加计算。如果我尝试在完成块内运行视图添加代码,Xcode会抛出一个错误,说明我在后台进程中无法使用布局引擎。因此,我在上找到一些代码,以便尝试在主线程上对方法进行排队:

let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.0 * Double(NSEC_PER_MSEC)))

dispatch_after(time, dispatch_get_main_queue(), {
    let returned = UIApplication.sharedApplication().sendAction("displayQRCode:", to: self.delegate, from: self, forEvent: nil)
})
DispatchQueue.main.async { 
  // your code here
}

但是,我不知道如何将参数“receiveAddr”和“amountBTC”添加到此函数调用中。我该怎么做,或者有人能建议一种向应用程序的主队列添加方法调用的最佳方法吗?

现代版本的Swift使用
DispatchQueue.main.async
向主线程调度:

let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.0 * Double(NSEC_PER_MSEC)))

dispatch_after(time, dispatch_get_main_queue(), {
    let returned = UIApplication.sharedApplication().sendAction("displayQRCode:", to: self.delegate, from: self, forEvent: nil)
})
DispatchQueue.main.async { 
  // your code here
}
要在主队列上进行调度,请使用:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
  // your code here
}
使用Swift的旧版本:

dispatch_async(dispatch_get_main_queue(), {
  let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
  delegateObj.addUIImage("yourstring")
})

正确的方法是在主队列中使用dispatch\u async,正如我在下面的代码中所做的那样

dispatch_async(dispatch_get_main_queue(), {
    (self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
})

如果你在闭包中使用self,不要忘记削弱self

dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
    if let strongSelf = self {
        self?.doSomething()
    }
})

Swift 2

使用尾部闭包,这将变成:

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}
尾随闭包是一种快速语法,它允许在函数参数范围之外定义闭包。有关更多信息,请参阅《Swift 2.2编程语言指南》

在dispatch\u async情况下,API是
func dispatch\u async(queue:dispatch\u queue\t,\ublock:dispatch\u block\t)
,因为
dispatch\u block\t
()->Void
的类型别名,Void是一个接收0个参数且没有返回值的闭包,块是函数的最后一个参数,我们可以在
dispatch\u async
的外部范围中定义闭包

NSOperationQueue.mainQueue().addOperationWithBlock({
    // Your code here
})
或者,您可以通过更少的代码和更多的功能来获取流行的:

Async.main {
    // Your code here
}

这里有一个很好的小全局函数,您可以添加它以获得更好的语法:

func dispatch_on_main(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}
用法

dispatch_on_main {
    // Do some UI stuff
}

Swift 3+和Swift 4版本:

DispatchQueue.main.async {
    print("Hello")
}
Swift 3和Xcode 9.2:

dispatch_async_on_main_queue {
    print("Hello")
}

在主线程上重新加载collectionView

DispatchQueue.main.async {
    self.collectionView.reloadData()
}

虽然您的建议是正确的,但我认为我的答案稍微好一点,因为它不调用UIApplication.sharedApplication,这是不寻常的,可能会使我的代码的其他读者感到厌烦。我的答案的范围仅限于重要的对象,而你的答案带来了辅助对象,需要我阅读更多的文档来准确了解我在做什么。我已经编辑了我的原始问题,以包含正确的函数调用。我原以为displayQRCode不够具体,但现在我们的评论是这样的。谢谢你指出这一点。这正是我要找的三行。。。现在你可以停止阅读我的思想了,你能解释一下我们为什么要这样做吗?因为它可以创造记忆周期——也就是说,我对某件事有很强的引用,它对我也有很强的引用。这意味着我们都不能将内存heap.method重命名为
OperationQueue.main.addOperation({}