views:

193

answers:

4

In my iPhone app I need to connect to a web server as this can take some time I'm using threads like this:

[NSThread detachNewThreadSelector:@selector(sendStuff) toTarget:self withObject:nil];

- (void)sendStuff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    //Need to get the string from the textField to send to server
    NSString *myString = self.textField.text;

    //Do some stuff here, connect to web server etc..

    [pool release];
}

On the row where I use self.textField I get a warning in console saying: void _WebThreadLockFromAnyThread(bool), 0x5d306b0: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.

How can I use the textField without getting this error?

A: 

This is indeed unsafe behaviour. The MainThread is the only one that should interface the UI. Have your thread return for instance a string to the mainthread and have a method there update the UI. You can do for instance do this by passing a selector to the other thread method, and then have the other thread call the selector on the mainthread.

niklassaers
+3  A: 

Perform any selectors that handle UI updates on the main thread. You can do this with the NSObject method -performSelectorOnMainThread:withObject:waitUntilDone:

Alex Reynolds
A: 

Why not:

[NSThread detachNewThreadSelector: @selector(sendStuff:) toTarget: self withObject: self.textField.text];

?

Graham Lee
A: 

It depends a little bit on what you want to do with the textField. If reading the value is the only thing, you can do:

[NSThread detachNewThreadSelector:@selector(sendStuff) toTarget:self withObject:self.textField.text];

- (void)sendStuff:(NSString*)myString {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    //Do someting with myString
    [pool release];
}

If you want to change a value on the textField you could:

[self.textField performSelectorOnMainThread:@selector(setText:) withObject:@"new Text"];
tonklon