Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSStreams Crashing Program!

All,

I've run it down to this point by commenting, breakpoints, etc. The program crashes at the marked code.

-(void) initNetworkCommunication
{
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.17.1", 2004, &readStream, &writeStream);

    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream open];//WHY MUST YOU CRASH HERE
    [outputStream open];//WHY MUST YOU CRASH HERE ALSO!!?!?

    NSLog(@"She be opened, sir!");
}

It doesn't crash if I comment out both of those, but it crashes if I comment out either one (so i.e. they are both causing the program to crash). There is no information that gets posted in the debugger either. All it does is send me to main.m and show me

"Thread 1: Program received signal: "EXC_BAD_ACCESS".

Thanks for the help in advance!

Edit: Here is my delegate method, but it doesn't even present the second active line in the log.

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {

    NSLog(@"stream event %i", streamEvent); //this doesn't post in the log when stream opened...

    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened");
            break;
        case NSStreamEventHasBytesAvailable:

            if (theStream == inputStream) {

                uint8_t buffer[1024];
                int len;

                while ([inputStream hasBytesAvailable]) {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) {

                        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                        if (nil != output) {

                            NSLog(@"server said: %@", output);
                            //[self messageReceived:output];

                        }
                    }
                }
            }
            break;


        case NSStreamEventErrorOccurred:

            NSLog(@"Can not connect to the host!");
            break;

        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            //[theStream release];
            theStream = nil;

            break;
        default:
            NSLog(@"Unknown event");
    }

} 
like image 331
Baub Avatar asked Jul 13 '11 22:07

Baub


3 Answers

What is happening is that the instance of the delegate class is being deallocated (causing EXC_BAD_ACCESS in the run loop) either because you didn't retain it, or you are using ARC (pretty likely) and you do not have a reference to it.

The solution is to either call retain on the delegate class, approximately like so:

SomeStreamDelegate *theDelegate = [[SomeStreamDelegate alloc] init];
[theDelegate retain];

Or if you do have ARC enabled, make an instance variable in the class where you alloc the delegate, and store your instance of connection there. That way ARC will not dealloc it, because the instance var counts as a reference.

like image 62
arjunyg Avatar answered Nov 11 '22 04:11

arjunyg


If you are using ARC, cast the streams like this :

inputStream = (__bridge NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;

This should prevent the crash. And keep in mind that if your streams are owned by a separate thread than the main thread that means the run loop needs to be called manually using run method after opening the streams.

like image 44
Anand Avatar answered Nov 11 '22 02:11

Anand


When I placed this in my View Controller (and not in a separate class) it worked perfectly.

like image 34
Baub Avatar answered Nov 11 '22 03:11

Baub