Wednesday, September 10, 2008

Controlling iPhone UI elements from a background thread

If you are trying to control UI elements (such as setting a UILabel's text) from a background thread, it will not work using the normal methods provided by the UI class.

For example, suppose you want to change the text of a UILabel. Normally, you'd just call:

[myLabel setText:@"this is my text"];

However, this won't work if you make that call from a background thread. The problem is the main thread needs to perform the UI updates. (Cocoa Fundamentals Guide, page 134: "All UIKit objects should be used on the main thread only.")

Fortunately, Apple provides a method to call an object's selector, but have the processing occur in the main thread. This is done via the performSelectorOnMainThread method. Here's how one would set a UILabel object's text from a background thread:

[myLabel performSelectorOnMainThread : @ selector(setText: ) withObject:@"this is my text" waitUntilDone:YES];

This is also very handy to know if you are trying to control the status of a UIActivityIndicatorView from within a background thread. Since the UIActivityIndicatorView is something that is normally used to indicate a background task is busy doing something, it's nice if you can control it's visible status via the background thread. Here's how you would do it:

[busyIcon performSelectorOnMainThread : @ selector(stopAnimating ) withObject:nil waitUntilDone:YES];

It's important to note that unlike the call when using the setText: selector, in this case you must omit the colon (:) in the selector name. If you don't your app will throw an exception when this message is passed to your object.

All content copyright © 2009  Brian Stormont, unless otherwise noted.   All rights reserved.