可以在后台线程上创建UIViewController吗?

时间:2015-11-03 23:37:18

标签: ios uiviewcontroller thread-safety uikit background-thread

相关:Is it ok to create a UIView on a background thread?

这个后台线程代码安全吗?

let viewController = MyViewController(nibName: nil, bundle: nil)
viewController.title = "My Title"
viewController.myProperty = true
dispatch_async(dispatch_get_main_queue(), {
    self.navigationController?.pushViewController(viewController, animated: true)
})

2 个答案:

答案 0 :(得分:1)

这取决于实例变量实际执行的操作。一般规则是后台线程运行的代码不应该触发任何UI更新,例如view.addSubview(..)view.setNeedsLayout等,然后使用后台线程使用视图控制器是安全的。

另一个例子是导航控制器。例如,一旦将视图控制器推送到导航堆栈,即使更新viewController.title也是危险的,因此您应该确保viewController.myProperty = true不会触发任何UI更新。就个人而言,我会在主线程中进行以下任务以确保安全:

dispatch_async(dispatch_get_main_queue(), {
  viewController.title = "My Title"
  viewController.myProperty = true
  ...
})

长话短说,您可以在后台线程中初始化新的UIView或UIViewController(或任何UIResponder),但是,您应该更改其主要线程内触发UI更新的任何属性。所以在后台创建但在主线程中更新。

答案 1 :(得分:0)

@ozgur的答案似乎已经过时了。如果您尝试在最新版本的Xcode(撰写本文时,版本11.5 )中通过后台线程创建UIViewController,则会出现以下错误:

-[UIViewController init] must be used from main thread only