ios - uikit 方法是否保证在主线程上运行?

标签 ios objective-c grand-central-dispatch

任何与 UI 相关的工作都需要在 iOS 的主线程上运行。有时我们需要做一些异步工作,比如下载图像,我们可能会使用 dispatch_async,当下载完成时,我们会得到主线程并像这样显示它:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage *overlayImage = [self faceOverlayImageFromImage:_image];
dispatch_async(dispatch_get_main_queue(), ^{
    [self fadeInNewImage:overlayImage];
});

});}

但是当我们在本地加载图像时,我们通常只是这样做而不在主线程上调度:
UIImageView *imageView = [[UIImageView alloc] initWithImage:@"myimage.png"];

我的问题是它们是否保证在主线程上运行?如果是,我们为什么要使用 dispatch_get_main_queue() 调度它?如果没有,为什么我们不需要在主线程上调度所有与 ui 相关的工作?

最佳答案

你很困惑。
给定的调用链要么在主线程上运行,要么在后台线程上运行。您处理的大部分代码都是通过系统事件调用的,并且保证在主线程上运行。只有少数情况下会从后台线程调用您的代码。只有在这些情况下,您才需要将 UIKit 调用包装在将调用重定向到主线程的代码中。
您的代码从后台线程运行的最常见原因是因为您以这种方式调用它 - 通常使用 Grand Central Dispatch。
您可能会调用一些这样的代码:

DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    //This code will be on a background thread
    //Do time-consuming work here

    //This calls back to the main thread.
    DispatchQueue.main.async { [weak self] in
        //Put your code to display your results in the UI here.
    }
}
View Controller 功能、按钮操作等总是在主线程上调用。如果系统在后台线程上调用了某个方法,它将被很好地记录在案。
一些采用完成处理程序的函数在后台线程上调用这些完成处理程序。 NSURLSession ( URLSession ) 类,例如,在默认为后台线程的委托(delegate)队列上调用其完成处理程序和委托(delegate)方法。因此,当您将完成处理程序传递给 URLSession 的实例时,您需要确保您的 UIKit 代码包含在对 dispatch_async() 的调用中。 (DispatchQueue.main.async() 在 Swift 3 中)或将代码传递给主线程以执行的类似方法。

关于ios - uikit 方法是否保证在主线程上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42428098/

相关文章:

ios - 在主队列上更改 View Controller 布局的最快方式?

ios - 如何为一定数量的设备分发 iOS 应用程序?

iphone - iPhone 上的 Xcode 和 iOS5.1 无法运行

objective-c - 如何在 iCloud 中保存 NSData

iphone - NSURLConnection 委托(delegate) didReceiveData 数据中的尾随字符

ios - 双击识别器不适用于 NSTimer 运行

iphone - 等待 iOS 中的多个事件?

ios - 添加带有后退按钮的 UINavigationController

objective-c - UIImage 到 CIImage - 大小减半?

iphone - 自定义 UITabBar 选定的标签图像,iOS 5 及更高版本