Reputation: 438
I already read 40 pages about threading, but still not sure about my case. I have an NSObject, that open a socket connection to a device. This Object handle all the communication, sending and receiving messages and so on. I would like, that this stuff works on separate thread. I tried something like this:
- (IBAction)connect:(id)sender {
SocketConnectionController *sock = [SocketConnectionController new];
[[sock initWithParams:ip.text :port.text.intValue] performSelectorInBackground:@selector(initWithParams::) withObject:nil];
[[SocketConnectionController sharedInstance] sendCommand:GET_ID_STRING];
}
As you see, I am sending some message by using the existing instance of SocketConnectionController, but it doesn't send anything. There maybe some leak of understanding my side. I am sure, that the connection is open because of flashing lights on device. Am I creating the thread on the right way? If so, how can I use it now?
1. UPDATE: I tried something like this:
NSOperationQueue* queue = [NSOperationQueue new];
SocketConnection *sock = [SocketConnection new];
[queue addOperation:sock];
but at the CPU graph I see, that the stuff still running on Thread 1 (mainThread). What am I doing wrong?
2. UPDATE I found out, that the run loop, that I need for the Input and Output Stream still running on the main Thread.
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
That's why the code of 1. Update don't work. So I need to create a new Thread and then a new run loop for this thread. That can not be done automatically by Cocoa-Framework like in the code before (performSelectorInBackground).
Upvotes: 0
Views: 595
Reputation: 438
I found the way to perform the socket connection on the separate thread:
NSThread * nThread;
- (NSThread *)networkThread {
nThread = nil;
nThread =
[[NSThread alloc] initWithTarget:self
selector:@selector(networkThreadMain:)
object:nil];
[nThread start];
NSLog(@"thread: %@, debug description: %@", nThread, nThread.debugDescription);
return nThread;
}
- (void)networkThreadMain:(id)unused {
do {
[[NSRunLoop currentRunLoop] run];
} while (YES);
}
- (void)scheduleInCurrentThread:(id)unused
{
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
}
-(BOOL) connectWithError:(NSString **) e
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"127.0.0.1", [server port], &readStream, &writeStream);
inputStream = (__bridge NSInputStream *) readStream;
outputStream = (__bridge NSOutputStream *) writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[self performSelector:@selector(scheduleInCurrentThread:)
onThread:[self networkThread]
withObject:nil
waitUntilDone:YES];
[inputStream open];
[outputStream open];
}
All you need is to input this code in the new class of type NSThread.
Upvotes: 2