NSStream and Sockets, NSStreamDelegate methods not being called

后端 未结 2 1766
礼貌的吻别
礼貌的吻别 2020-12-07 18:03

I\'ve followed the guide Setting Up Socket Streams and have effectively duplicated that code in my class. No matter what I try the delegate methods just don\'t seem to get c

相关标签:
2条回答
  • 2020-12-07 18:49

    In the lines like this:

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

    Instead of using [NSRunLoop currentRunLoop] I changed it to [NSRunLoop mainRunLoop].

    EDIT 2011-05-30:

    The reason this did not work is because I was setting up the sockets in a background thread via +[NSThread detachNewThreadSelector:toTarget:withObject:].

    Doing it that way created a new run loop, which after reading the run loop developer documentation I discovered that you need to tell the NSRunLoop to run manually.

    Running it in the same run loop as the main thread was fine on performance, though I was able to squeeze a bit more performance out by writing a wrapper class and running all network I/O on a background thread.

    0 讨论(0)
  • 2020-12-07 18:56

    That solution will work if & only if you don't have blocking work on thread 0. This is often OK, but a better solution is to create a new thread (i.e. using a class method to create the thread on demand) and then enqueue on that thread. i.e.

    + (NSThread *)networkThread {
        static NSThread *networkThread = nil;
        static dispatch_once_t oncePredicate;
    
        dispatch_once(&oncePredicate, ^{
            networkThread =
                 [[NSThread alloc] initWithTarget:self
                                         selector:@selector(networkThreadMain:)
                                           object:nil];
            [networkThread start];
        });
    
        return networkThread;
    }
    
    + (void)networkThreadMain:(id)unused {
        do {
            @autoreleasepool {
                [[NSRunLoop currentRunLoop] run];
            }
        } while (YES);
    }
    
    - (void)scheduleInCurrentThread
    {
        [inputstream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                               forMode:NSRunLoopCommonModes];
    }
    

    With this, you can schedule the input stream using:

    [self performSelector:@selector(scheduleInCurrentThread)
                 onThread:[[self class] networkThread]
               withObject:nil
            waitUntilDone:YES];
    

    This will allow you to run your network operations without worrying about deadlocks anymore.

    0 讨论(0)
提交回复
热议问题