Re: More on: converting C-strings to NSString
Re: More on: converting C-strings to NSString
- Subject: Re: More on: converting C-strings to NSString
- From: email@hidden (mikevannorsdel)
- Date: Tue, 23 Oct 2001 17:40:40 -0600
Doing UI control from a secondary thread is not safe. You'll get rouge
leaks and crashes. You'll need to use DO for this where the worker
thread connects to the main thread and sends a message to a proxy of
your UI controller object to update the text field with a passed string
value. See NSConnection to see how to do this. Basically, you
instantiate an NSConnection object in the main thread with two NSPorts,
one for sending and one for receiving, and set your UI controller object
as the connection's root object. When you detach the new worker thread,
pass the same two NSPorts via an NSArray to the new thread selector. In
the new thread, create another NSConnection using the two passed
NSPorts. Remember to switch the ports orders so the sending port for
the main thread will be the receiving port for the worker thread. Once
the NSConnection is created in the worker thread, get a proxy for the UI
controller object from the connection. You can then communicate with
the UI controller in the main thread from the secondary thread. It will
look like this:
//somewhere in the main thread before detaching worker thread
port1=[NSPort port];
port2=[NSPort port];
mainConnection=[[NSConnection alloc] initWithReceivePort:port1
sendPort:port2];
[mainConnection setRootObject:UIController];
portArray=[[NSArray alloc] initWithObjects:port2, port1, nil];
[NSThread detachNewSelector:@selector(workerMethodWithPorts:)
toTarget:theTarget withObject:portArray];
//the worker thread method
- (void)workerMethodWithPorts:(NSArray*)ports
{
NSAutoreleasePool * localPool=[[NSAutoreleasePool alloc] init];
id UIProxy=[[NSConnection connectionWithReceivePort:[ports
objectAtIndex:0] sendPort:[ports objectAtIndex:1]] rootProxy];
...
do work
...
[UIProxy updateTextFieldWithString:secondbuffer];
[localPool release];
}
//Here's the method for updating in the UIController in the main thread
- (oneway void)updateTextFieldWithString:(in NSString*)text
{
[results setStringValue:text];
}
Again, see NSConnection for the details.
On Tuesday, October 23, 2001, at 01:10 PM, email@hidden wrote:
Also, you can't do [results setStringValue:secondbuffer] anywhere
other than the main thread.
But I need to. I can not have my interface lock up until the rest of
the program completes.
What I am doing, is the following:
1. creating a new thread
2. the new thread calls popen() (which, in essence forks(), exec()-s
and pipes output to a FILE pointer).
3. the new thread waits for the process to finish and then displays the
output in a NSTextView object
4. the new thread exits