1

I detach a new NSThread withObject:self so that the thread can callback the main thread as a delegate. However, I also need the new thread to be able to read some values in the parent. With NSThread, I can only pass one object withObject, and I'm using that to pass self because of the delegate methods. Is there a way my new thread can read values from it's parent? Perhaps through the self object that is passed to it?

Here's where I launch the thread:

MulticastDaemon* multicastDaemon = [[MulticastDaemon alloc] init];
[NSThread detachNewThreadSelector:@selector(doWorkWithDelegate:)
                         toTarget:multicastDaemon
                       withObject:self];

I want to pass a multicast IP address and port number to the daemon, so he knows what to listen on, but I'm not sure how to get those values to multicastDaemon.

How can multicastDaemon access those values?

Adam
  • 913
  • 1
  • 9
  • 26

3 Answers3

1

Yes, you can access the variables by making them properties and then doing something like this (you don't say what the class is that this call is made from, so I've called it MyClass):

@implementation MulticastDaemon

-(void) doWorkWithDelegate:(MyClass*) cls
{
    cls.value1 = 12;
    ...
}

...

@end

EDIT: Corrected implementation.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
1

You'd better use the subclass of NSOperation and then add it to the NSOperationQueue. You can add any additional parameters to that operation subclass.

There is also another advantage of NSOperation over NSThread. NSOperation and NSOperationQueue are build on top of the GCD and threading is far more optimal then NSThread.

But you can also simply add some properties to your MulticastDaemon.

Max
  • 16,679
  • 4
  • 44
  • 57
0

You can change your MulticastDaemon's interface slightly so that you set the delegate before creating the new thread. Then you free up the withObject: slot to pass something else along. This avoids accessing variables across threads.

Either:

 MulticastDaemon* multicastDaemon = [[MulticastDaemon alloc] initWithDelegate:self];
[NSThread detachNewThreadSelector:@selector(doWorkWithInformation:)
                         toTarget:multicastDaemon
                       withObject:operatingInfo];

Or

MulticastDaemon* multicastDaemon = [[MulticastDaemon alloc] init];
[multicastDaemon setDelegate:self];

Otherwise, you'll have to create a method that the daemon can call on its delegate that gathers and packages up the information to pass back. In that case, you'll probably have to start worrying about thread safety.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Thread safety is a new concept for me. I will have to do some reading. What I ended up doing is just doing something like: port = [delegate portNumber]; Because self was delegate, the thread has easy access like this, right? – Adam Nov 15 '11 at 22:58
  • 1
    Yes. The thread safety issue is that it's possible for the value to change _while_ you are accessing it, resulting in your retrieving an invalid result. If there's no chance of the port number changing once the daemon has been started, you don't need to worry. – jscs Nov 16 '11 at 07:52
  • I did some reading, and I agree with your comment. In my case, I don't think I need to worry. I read the port/address values into new values and then the port/address are free to change. If they do, the thread is cancelled and another thread is launched with the new values. I can't see any case where values might be written while they are being read. – Adam Nov 17 '11 at 03:53
  • That will only be safe if you're talking about primitives (`int`s/`float`s/`struct`s, etc.). If the port number and other values are objects, you need to `copy` them. Otherwise you're still using the same piece of memory. – jscs Nov 17 '11 at 07:27