开发者

NSStreams Crashing Program!

开发者 https://www.devze.com 2023-03-20 07:54 出处:网络
All, I\'ve run it down to this point by commenting, breakpoints, etc. The program crashes at the marked code.

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

} 


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.


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.


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


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.


Try this out once,

NSInputStream * inputStream = objc_unretainedObject(readStream);

May be a casting issue

0

精彩评论

暂无评论...
验证码 换一张
取 消