If you're a developer, you've probably encountered the error message "Only the original thread that created a view hierarchy can touch its views." This error message is a common one in iOS development, and it can be frustrating to deal with.
In this guide, we'll explain what this error message means, why it happens, and how to troubleshoot it. We'll also provide some tips to help you avoid this error message in the future.
What does "Only the Original Thread that Created a View Hierarchy Can Touch Its Views" mean?
This error message means that you're trying to update a view from a thread that didn't create the view. In iOS development, all user interface updates must happen on the main thread. If you try to update a view from a background thread, you'll get this error message.
Why does this error happen?
This error happens because UIKit, the framework that provides the core components for iOS apps, is not thread-safe. This means that you can't modify the user interface from a background thread.
How to troubleshoot "Only the Original Thread that Created a View Hierarchy Can Touch Its Views" error?
Here are some troubleshooting solutions to help you fix this error message:
1. Move the view updates to the main thread
The easiest way to fix this error message is to move the view updates to the main thread. You can do this by wrapping the view updates in a DispatchQueue.main.async
block.
DispatchQueue.main.async {
// Update the view here
}
2. Use performSelector(onMainThread:)
If you're working with Objective-C code, you can use the performSelector(onMainThread:)
method to update the view on the main thread.
[self performSelectorOnMainThread:@selector(updateView) withObject:nil waitUntilDone:NO];
3. Use a GCD serial queue
If you have a lot of view updates to perform, you can use a GCD serial queue to perform them on the main thread.
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.sync {
// Update the view here
}
4. Use OperationQueue
If you have a lot of view updates to perform and you want more control over the concurrency, you can use OperationQueue
.
let operationQueue = OperationQueue()
operationQueue.addOperation {
// Update the view here
}
Tips to avoid "Only the Original Thread that Created a View Hierarchy Can Touch Its Views" error
Here are some tips to help you avoid this error message in the future:
- Always perform user interface updates on the main thread.
- Use a GCD serial queue or
OperationQueue
to perform a lot of view updates on the main thread. - Use
performSelector(onMainThread:)
if you're working with Objective-C code.
FAQ
Q1. Why is UIKit not thread-safe?
UIKit is not thread-safe because it was designed to be used on the main thread. This makes it easier for developers to create responsive and performant user interfaces.
Q2. Can I update the user interface from a background thread?
No, you shouldn't update the user interface from a background thread. Doing so can lead to unpredictable behavior and crashes.
Q3. What happens if I ignore this error message?
If you ignore this error message, your app may crash or exhibit unpredictable behavior. It's important to fix this error message as soon as possible.
Q4. Can I use DispatchQueue.global(qos:)
to update the user interface?
No, you shouldn't use DispatchQueue.global(qos:)
to update the user interface. This queue is designed for background tasks and doesn't guarantee that the updates will happen on the main thread.
Q5. Can I update the user interface from a closure passed to UIView.animate(withDuration:)
?
Yes, you can update the user interface from a closure passed to UIView.animate(withDuration:)
. The closure is executed on the main thread, so it's safe to update the user interface from it.