Swift iOS-在主队列上调用函数与';主队列上的函数中有什么?

Swift iOS-在主队列上调用函数与';主队列上的函数中有什么?,ios,swift,multithreading,grand-central-dispatch,Ios,Swift,Multithreading,Grand Central Dispatch,在我的应用程序中,我在下面的完成处理程序中启用了一些功能,但是为了简单起见,我在这个示例中只使用了一个按钮。我之所以这样说,是因为有人会看这个例子,说因为只有一个按钮可以使事情变得简单,所以使用第一个选项,这对于一个按钮来说是有意义的,但对于几个按钮来说是没有意义的。此外,这个问题可能涉及到在不同线程上运行的任何东西,然后是主线程,而不是CaptureSesion 我有一个AVFoundation CaptureSession完成处理程序,它位于与主队列不同的线程上。当它运行时,它会将按钮更新为

在我的应用程序中,我在下面的完成处理程序中启用了一些功能,但是为了简单起见,我在这个示例中只使用了一个按钮。我之所以这样说,是因为有人会看这个例子,说因为只有一个按钮可以使事情变得简单,所以使用第一个选项,这对于一个按钮来说是有意义的,但对于几个按钮来说是没有意义的。此外,这个问题可能涉及到在不同线程上运行的任何东西,然后是主线程,而不是CaptureSesion

我有一个AVFoundation CaptureSession完成处理程序,它位于与主队列不同的线程上。当它运行时,它会将按钮更新为
。isEnabled=true

我也可以

•1。直接更新主队列上的函数:

... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
)}
•2。将按钮放入函数中,然后在主队列上更新该函数:

... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
)}

func enableRecordButton(){
    recordButton.isEnabled = true
}
... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
)}

func enableRecordButton(){
    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
}
•3。更新主队列上的函数和函数内部的内容:

... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
)}

func enableRecordButton(){
    recordButton.isEnabled = true
}
... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
)}

func enableRecordButton(){
    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
}

这3个组件之间有什么区别?

通常,您应该只在主线程上更新UI组件。因此

DispatchQueue.main.async { [weak self] in
       self?.recordButton.isEnabled = true
}
绝对有道理。因为您希望按钮被启用,并且它是一个UI修改,所以您希望它位于主线程中。因此,
DispatchQueue.main.async
闭包中的所有语句都将在主线程上执行

在哪里

DispatchQueue.main.async { [weak self] in
       self?.enableRecordButton()
}
方法
enableRecordButton
将在主线程上执行。这意味着
enableRecordButton
方法中的所有语句以及它调用的所有后续方法都将在主线程上执行

在你的例子中,如果你想要实现的只是启用一个按钮,那么把它放在一个单独的函数中就没有多大意义了。您得到的唯一好处是,您可以通过在任何地方调用
enablecordbutton
函数来启用该按钮,而无需再次重复相同的语句

最后

... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
)}

func enableRecordButton(){
    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
}
这对你来说毫无意义。声明

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
将已经确保
enableRecordButton
中的所有语句将在主线程上执行,因此在
enableRecordButton
中添加
DispatchQueue.main.async
没有意义

func enableRecordButton(){
    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
}
只有当您的代码中有多个点可以调用
enableRecordButton
,并且可以在非主线程上调用它时,这才可能派上用场,在这种情况下,您可以安全地删除它

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
只需在完成处理程序中调用
self?.enableRecordButton()
,在
enableRecordButton
函数中调用
DispatchQueue.main.async
,即可确保所有语句都在主线程上执行


希望它能有所帮助。通常,您应该只在主线程上更新UI组件。因此

DispatchQueue.main.async { [weak self] in
       self?.recordButton.isEnabled = true
}
绝对有道理。因为您希望按钮被启用,并且它是一个UI修改,所以您希望它位于主线程中。因此,
DispatchQueue.main.async
闭包中的所有语句都将在主线程上执行

在哪里

DispatchQueue.main.async { [weak self] in
       self?.enableRecordButton()
}
方法
enableRecordButton
将在主线程上执行。这意味着
enableRecordButton
方法中的所有语句以及它调用的所有后续方法都将在主线程上执行

在你的例子中,如果你想要实现的只是启用一个按钮,那么把它放在一个单独的函数中就没有多大意义了。您得到的唯一好处是,您可以通过在任何地方调用
enablecordbutton
函数来启用该按钮,而无需再次重复相同的语句

最后

... completionHandler{(

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
)}

func enableRecordButton(){
    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
}
这对你来说毫无意义。声明

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
将已经确保
enableRecordButton
中的所有语句将在主线程上执行,因此在
enableRecordButton
中添加
DispatchQueue.main.async
没有意义

func enableRecordButton(){
    DispatchQueue.main.async { [weak self] in
           self?.recordButton.isEnabled = true
    }
}
只有当您的代码中有多个点可以调用
enableRecordButton
,并且可以在非主线程上调用它时,这才可能派上用场,在这种情况下,您可以安全地删除它

    DispatchQueue.main.async { [weak self] in
           self?.enableRecordButton()
    }
只需在完成处理程序中调用
self?.enableRecordButton()
,在
enableRecordButton
函数中调用
DispatchQueue.main.async
,即可确保所有语句都在主线程上执行


希望它有帮助

我认为在函数中再次添加DispatchQueue.main.async{}是无用的,因为您已经在主线程上,需要更新用户界面。假设在更新按钮后需要安排某些任务,可以添加另一个DispatchQueue.main.async{}将其放入串行队列中,该队列将在更新按钮后执行。但是在任何情况下,更新都只在主线程上进行,并且是串行的。

我认为在函数中再次添加DispatchQueue.main.async{}是无用的,因为您已经在主线程上,需要更新用户界面。假设在更新按钮后需要安排某些任务,可以添加另一个DispatchQueue.main.async{}将其放入串行队列中,该队列将在更新按钮后执行。但是在每种情况下,更新都只在主线程上进行,并且是串行的。

从技术上讲,这三种更新都将获得相同的结果。它更多的是关于代码组织、可维护性和可读性

对于#1,您可能在完成处理程序中执行与更新UI无关的业务逻辑。将UI更新移动到自己的方法会更干净,例如,在视图拥有该按钮(以及您提到的其他UI控件)的UIViewController中。这样做的好处是,您可以从应用程序的其他地方通过相同的调用启用UI控件,并且可以针对它编写测试。如果需要,您还可以更好地测试此完成处理程序的业务逻辑