PDA

View Full Version : NSThread causing UIView to freeze.




TrevorB
Dec 7, 2009, 01:17 PM
Hey there.. I've only been at this for a week, plugging a way so far, but hit a glitch where I thought I should ask for some help.

I'm trying to animate an object on a UIView. I've decided to do this by subclassing NSThread, and having that pass a message back to my View Contoller after a delayed interval.

This appears to work OK, the thread is launched, the messages are passed back and forth, except that the UIView doesn't appear to update until the Thread's main method is complete. I can see the methods being called proplerly (NSLog's work as I think they should)... I'd rather have the threads run concurrently so that one can update the other.

Any ideas what I might be doing wrong?

Code Snippets:

TestThread.m:

- (void) main {
NSAutoreleasePool *autorelease = [[NSAutoreleasePool alloc] init];
NSLog(@"Thread Started");
[NSThread sleepForTimeInterval:2.0];
NSLog(@"Thread Still here...");
[viewController threadMessage];
[NSThread sleepForTimeInterval:10.0];
NSLog(@"Thread Still here2...");
[autorelease release];
}

- (void) setParent:(id)sender {
viewController = sender;
NSLog(@"View Contoller set");
}
@end

AppDelegate.m:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];


TestThread *myThread = [[TestThread alloc] init];
[myThread setParent:viewController];
[myThread start];
}

ViewController.m:

- (void)threadMessage {
NSLog(@"ThreadMessage");
CGPoint touchPoint;
touchPoint.x = 20;
touchPoint.y = 20;

target.center = touchPoint;

yLabel.text = @"New Message";
NSLog(@"ThreadMessage finished");

}



The problem is that I see "ThreadMessage finished" in the console, but the animations produced by "target.center = touchPoint" and "yLabel.text..." don't show up until after the 10 second delay produced by TestThread.m's " [NSThread sleepForTimeInterval:10.0];"

Any help would be appreciated!



TrevorB
Dec 7, 2009, 01:30 PM
Aha! Figured it out from here:

http://stackoverflow.com/questions/1344653/painting-a-uiview-from-a-background-nsthread

"All user-interface classes are not thread-safe and must be called from the main thread"

So instead of:

[viewController threadMessage];

I need...

[viewController performSelectorOnMainThread:@selector(threadMessage) withObject:nil waitUntilDone:YES];

Works great now!

icewing
Dec 8, 2009, 01:54 PM
Thanks for doing such a great follow up! That's bound to be very helpful for someone in the future. I wish more people took the time to be that detailed.