在后台线程上创建 UIViewController 可以吗?
Is it OK to create a UIViewController on a 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)
})
这取决于实例变量的实际作用。一般规则是后台线程的代码 运行 不应触发任何 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 更新。所以在后台创建但在主线程中更新。
@ozgur 的回答似乎已经过时了。如果您尝试在最新版本 Xcode(版本 11.5 在撰写本文时)中从后台线程创建 UIViewController,那么您将收到以下错误:
-[UIViewController init] must be used from main thread only
相关: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)
})
这取决于实例变量的实际作用。一般规则是后台线程的代码 运行 不应触发任何 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 更新。所以在后台创建但在主线程中更新。
@ozgur 的回答似乎已经过时了。如果您尝试在最新版本 Xcode(版本 11.5 在撰写本文时)中从后台线程创建 UIViewController,那么您将收到以下错误:
-[UIViewController init] must be used from main thread only