Objective c 独立线程上的套接字通信

Objective c 独立线程上的套接字通信,objective-c,multithreading,sockets,Objective C,Multithreading,Sockets,我已经读了40页关于线程的文章,但仍然不确定我的案例。 我有一个NSObject,它打开到设备的套接字连接。该对象处理所有通信、发送和接收消息等。我想,这东西在单独的线程上工作。我试过这样的方法: - (IBAction)connect:(id)sender { SocketConnectionController *sock = [SocketConnectionController new]; [[sock initWithParams:ip.text :port.text.intValue

我已经读了40页关于线程的文章,但仍然不确定我的案例。 我有一个NSObject,它打开到设备的套接字连接。该对象处理所有通信、发送和接收消息等。我想,这东西在单独的线程上工作。我试过这样的方法:

- (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];
NSOperationQueue* queue = [NSOperationQueue new];
SocketConnection *sock = [SocketConnection new];
[queue addOperation:sock]; 
}

如您所见,我正在使用SocketConnectionController的现有实例发送一些消息,但它不发送任何消息。也许有一些对我的理解的漏洞。我确信,由于设备上的闪光灯,连接已打开。我是否以正确的方式创建线程?如果是,我现在如何使用它

1。更新: 我试过这样的方法:

- (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];
NSOperationQueue* queue = [NSOperationQueue new];
SocketConnection *sock = [SocketConnection new];
[queue addOperation:sock]; 
但是在CPU图上,我看到,这些东西仍然在线程1(主线程)上运行。 我做错了什么

2。更新 我发现,运行循环,我需要的输入和输出流仍然在主线程上运行

[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

这就是为什么1的代码。更新不起作用。所以我需要创建一个新线程,然后为这个线程创建一个新的运行循环。Cocoa框架无法像前面的代码(performSelectorInBackground)那样自动完成这一点

我找到了在单独的线程上执行套接字连接的方法:

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];
}

您只需在NSThread类型的新类中输入此代码

如果
SocketConnectionController
是单例(
sharedInstance
),则不应在其上调用
new
。由于
new
alloc
加上
init
,因此使用参数调用第二个init也很奇怪。最后,要执行的选择器不应该是另一个init,尤其是一个接受两个参数的init,而不是您试图传递给它的(
nil
)的init。因此,要将此参数传递给参数,我需要类似于:performSelectorInBackground:@(initWithParams:)withObject:@“192.168.0.1”withObject:80?现在如何使用这个新实例呢?当您直接调用它时,为什么还要在后台调用
initWithParams::
?(这仍然没有澄清单身问题。)好的。在需要线程之前,我使用[[[SocketConnectionController alloc]initWithParams:ip.text portnr:port.text.intValue];]创建套接字实例,效果很好。现在我需要几乎相同的只在线程。怎么做?我猜是因为我不知道
SocketConnectionController
在内部做什么,但是你能像以前一样创建它,然后使用
sendCommand
作为你想要在后台执行的事情(并获得作为
withObject
参数发送的\u ID\u字符串)?两周前你在哪里?是的,CocoaAsyncSocket也可以解决这个问题。