8

全部,

我已经通过注释、断点等将它运行到这一点。程序在标记的代码处崩溃。

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

如果我注释掉这两个它不会崩溃,但是如果我注释掉其中一个它会崩溃(即它们都导致程序崩溃)。调试器中也没有发布任何信息。它所做的只是将我发送到 main.m 并显示给我看

“线程 1:程序接收信号:“EXC_BAD_ACCESS”。

我在这里先向您的帮助表示感谢!

编辑:这是我的委托方法,但它甚至没有在日志中显示第二个活动行。

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

} 
4

5 回答 5

4

正在发生的事情是委托类的实例正在被释放(在运行循环中导致 EXC_BAD_ACCESS),或者因为您没有保留它,或者您正在使用 ARC(很可能)并且您没有对它的引用。

解决方案是在委托类上调用保留,大致如下:

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

或者,如果您确实启用了 ARC,请在分配委托的类中创建一个实例变量,并将您的连接实例存储在那里。这样 ARC 就不会释放它,因为实例 var 算作引用。

于 2013-05-27T15:52:09.740 回答
2

如果您使用的是 ARC,请像这样转换流:

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

这应该可以防止崩溃。请记住,如果您的流由与主线程不同的线程拥有,则意味着在打开流后需要使用 run 方法手动调用运行循环。

于 2014-02-27T08:26:14.813 回答
1

当我将它放在我的视图控制器中(而不是在单独的类中)时,它工作得很好。

于 2011-07-18T16:21:43.473 回答
0

我有一个类似的问题,我的应用程序会在 -handleEvent 回调中崩溃,并且具有巨大的 streamEvent 编号。我通过确保初始化 NSStream 对象(输入和输出)并我的 VC 计划使用的 NetworkClient 对象的 -init 方法中打开到服务器的连接来解决它。

于 2013-04-06T19:48:18.967 回答
-2

试试这个,

NSInputStream * inputStream = objc_unretainedObject(readStream);

可能是选角问题

于 2011-07-14T09:20:42.953 回答