Re: NSThread and UI
Re: NSThread and UI
- Subject: Re: NSThread and UI
- From: Chris Hanson <email@hidden>
- Date: Sun, 20 Jul 2008 17:08:29 -0700
On Jul 20, 2008, at 2:01 PM, Torsten Curdt wrote:
So in the following naive code I would have to either wrap the calls
to the progressIndicator object through a
performSelectorOnMainThread or could send NSNotifications to update
it on the main thread.
Notifications — whether via NSNotificationCenter or Key-Value
Observing — are synchronous. Thus they're delivered in the same
thread in which they're posted, which in multi-threaded code generally
isn't what you want.
I am also wondering whether using NSRunCriticalAlertPanel() in the
thread is OK or not.
I wouldn't. Even if you can do it, it's probably a layering
violation. Your operation is generally happening at the model level,
so you shouldn't directly do UI from it.
Instead of using -[NSObject
detachNewThreadSelector:toTarget:withObject:] to encapsulate all of
the threaded operation into one method, I'd create a separate object
to do that stuff, and I'd give it a delegate, notification, or KVO API
for things like progress updates that the UI can observe.
For example, the API might look like this:
@protocol ConversionOperationDelegate;
@interface ConversionOperation : NSObject {
id<ConversionOperationDelegate> delegate;
float progress;
// and any other properties, of course
}
- (id)init;
@property(readwrite, assign) id<ConversionOperationDelegate>
delegate;
// other properties too, of course, for set-up before starting the
conversion
- (void)start;
@property(readonly) float progress;
// a property that can be bound to and that gets updated on the
main thread
@end
@protocol ConversionOperationDelegate <NSObject>
@required
- (void)conversionOperation:(ConversionOperation *)operation
encounteredError:(NSError *)error;
@optional
- (void)conversionOperationDidStart:(ConversionOperation *)operation;
- (void)conversionOperationDidFinish:(ConversionOperation
*)operation;
@end
I would use -[NSObject
performSelectorOnMainThread:withObject:waitUntilDone:] to actually
invoke the internal-to-ConversionOperation methods that wind up
invoking delegate methods and changing the progress property, so don't
have to worry about things happening on the background thread.
Note that if you're targeting Leopard or later, you can use
NSOperation to encapsulate some of this. However, you'll still have
to use techniques like -
performSelectorOnMainThread:withObject:waitUntilDone: to update your
detailed progress information in a way that doesn't cause thread-
synchronization issues.
-- Chris
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden