0

I am writing an iOS app using InputStream and OutputStream. However, I find that I can both read and write from the streams without scheduling them in a RunLoop!

I here is my ThreadFunc. Notice that I have commented out all the runLoop code, but it still works!

@objc func threadFunc(){
    var dataToSend: Data?;

    print("Inside threadFunc loop!");

    //self.m_ReadStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.commonModes );
    self.m_ReadStream!.open();

    //self.m_WriteStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.commonModes );
    self.m_WriteStream!.open()

    var once = false;

    while( !m_Calcelled ){
        let wStat = self.m_WriteStream?.streamStatus;
        let rStat = self.m_ReadStream?.streamStatus;

        if( dataToSend == nil && self.m_Lock.lock(before: Date(timeIntervalSinceNow: 10 ) )){
            dataToSend = self.m_DataToSend; // Make local copy
            self.m_DataToSend = nil;
            self.m_Lock.unlock();
        }

        if( dataToSend != nil && wStat == .open ){
            let totalBytesSent = self.sendDataBlock( d:dataToSend! );
            if( totalBytesSent == dataToSend?.count ){
                print("successfully sent the packet.");
            }
        }
        //let untilDate: Date = Date(timeIntervalSinceNow: 5 );
        //print("SocketThread. Calling runLoop...");
        //RunLoop.current.run( mode: .defaultRunLoopMode, before: untilDate );
        //print("SocketThread is waiting for action....");
        //sleep(1);   // Sleep for 1 second...
    }
}
Vipul
  • 1
  • 4

1 Answers1

1

As the docs note:

Unless the client is polling the stream, it is responsible for ensuring that the stream is scheduled on at least one run loop and that at least one of the run loops on which the stream is scheduled is being run.

You're polling the stream. This isn't generally how streams are meant to be used, but since you are, it doesn't require a runloop.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks a lot. That makes sense. Unfortunately, my reputation is to low to up-vote your answer…. BTW - I don't really poll - well not directly. I read from the stream when I know there will be data from the server. All this is on a thread separate from the main thread, so should be fine? I am an old-timer and still use mutex/threads... – Vipul Oct 04 '18 at 20:18
  • You shouldn't use threads on iOS. It's bad for performance, both speed and especially energy. Generally you should also avoid mutexes for the same reason. There are much better tools that allow the system to optimize performance. See Migrating Away from Threads for Apple's introduction to how to replace threads with GCD. https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html (There's no need to upvote; but if the answer is correct you should accept it so others will find it in the future.) – Rob Napier Oct 04 '18 at 21:12
  • (That said, NSStream generally works with runloops rather than GCD. There's no need for threads at all. It's just a waste of memory and unnecessary processor context switches.) – Rob Napier Oct 04 '18 at 21:15