NSStreams Crashing Program!
Asked Answered
B

5

8

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");
    }

} 
Bresee answered 13/7, 2011 at 22:26 Comment(2)
Thread 1 is not the main thread. It is probably being used by the streams while they are opening. The crash could be occuring in your delegate's stream:handleEvent: method, so I would suggest starting there.Audie
If there is a crash, there is a backtrace. Post it.Yul
B
1

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

Bresee answered 18/7, 2011 at 16:21 Comment(1)
that mean, the local object cannot be retained. Except move the whole thing to UIVIewController, you can delcare the local object as a iVar or property of the view controller, doing that, i have managed to pulled out of carshes :)Contrarious
J
4

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.

Jackofalltrades answered 27/5, 2013 at 15:52 Comment(0)
S
2

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.

Simulate answered 27/2, 2014 at 8:26 Comment(1)
This is a better and more accurate answerNatality
B
1

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

Bresee answered 18/7, 2011 at 16:21 Comment(1)
that mean, the local object cannot be retained. Except move the whole thing to UIVIewController, you can delcare the local object as a iVar or property of the view controller, doing that, i have managed to pulled out of carshes :)Contrarious
L
0

I had a similar issue where my app would crash in the -handleEvent callback with a huge streamEvent number. I resolved it by making sure I initialize the NSStream objects (input and output) AND open a connection to the server in the -init method of the NetworkClient object which my VC plans to use.

Lurcher answered 6/4, 2013 at 19:48 Comment(0)
L
-2

Try this out once,

NSInputStream * inputStream = objc_unretainedObject(readStream);

May be a casting issue

Linger answered 14/7, 2011 at 9:20 Comment(2)
If ARC were enabled, that code wouldn't compile as written anyway. This answer doesn't make sense.Yul
oops....may be i was in ios5 streams in my mind fully.. I didnt quite add this: If the app is in ios5 then <Answer>.. my bad.. as bbum said, this applies only in a automatic reference counted environment..Linger

© 2022 - 2024 — McMap. All rights reserved.