【问题标题】:UIKit and GCD thread-safetyUIKit 和 GCD 线程安全
【发布时间】:2013-04-24 08:53:22
【问题描述】:

许多帖子说 UIKit 完全不是线程安全的。现在在 GCD 的 Apple 文档中,我们可以读到 DRAWING 不是线程安全的。那么这样的代码可以吗:

dispatch_async(^{

//do some work
if(!self.window.rootViewController.presentedViewController && )
    [self.window.rootViewController class] == anotherClass)
  {
      dispatch_async(dispatch_get_main_queue(), ^{  //do some work  });
  }

});

【问题讨论】:

  • 好吧,考虑到 rootViewController 被声明为 @property(nonatomic,retain) UIViewController *rootViewController,我认为不会。
  • 为什么不在主线程的调度中进行测试。在主线程以外的线程上弄乱 UI 元素是在玩火,即使它在 iOS 6 中运行,您的应用程序在 iOS 7 中也可能会严重失败......
  • 因为该块在一个while循环中,该循环在另一个dispatch_async()中,否则该循环会阻塞主线程。

标签: ios uikit grand-central-dispatch


【解决方案1】:

我个人的看法是,到目前为止,您所听到的内容具有误导性。

这是来自 Apple 的 UIKit Framework Reference 的引用,归功于类似的线程 here

注意:在大多数情况下,UIKit 类只能从 应用程序的主线程。对于类来说尤其如此 派生自 UIResponder 或涉及操纵您的 应用程序的用户界面。

另外,请注意,根据release notes found here,从 iOS4 开始,与您的假设相反,

在 UIKit 中绘制到图形上下文现在是线程安全的。 具体来说:

  • 用于访问和操作图形上下文的例程现在可以正确处理驻留在不同线程上的上下文。
  • 字符串和图像绘制现在是线程安全的。
  • 现在可以安全地在多个线程中使用颜色和字体对象。

事实上,在 WWDC 2012 会议“构建并发用户界面”中,Apple 工程师在后台线程中演示了如何绘制到 图像图形上下文

我的收获:

  • 您可以使用多线程绘图,但不要假设任何东西。仅使用 Apple 明确声明的内容。
  • 再一次,什么都不做。不要碰任何从后台线程继承的UIResponder的UIKit东西。

【讨论】:

    【解决方案2】:

    在此示例中,您没有更改任何值,所以是的,没关系。不是从后台线程更新 UI。

    【讨论】:

    • 这几乎是我的问题,很多人说你根本不应该从另一个线程触摸 UIKit,但后来我读到它是更新、重绘,这不是线程安全的,有点令人困惑。
    • 阅读有关多线程、块和相关内容的 Apple 指南,您将了解事物是如何在幕后实现的。然后你会明白为什么在非线程安全代码上读取或检查值是安全的,以及为什么改变或更新值不是上帝的主意。 UIKit 也不例外,它只是另一个非线程安全的类集合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2014-03-04
    • 1970-01-01
    相关资源
    最近更新 更多