Программа сбоя NSStreams! - PullRequest
       35

Программа сбоя NSStreams!

8 голосов
/ 14 июля 2011

Все,

Я дошел до этого момента, комментируя, точки останова и т. Д. Программа вылетает с помеченным кодом.

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

} 

Ответы [ 5 ]

4 голосов
/ 27 мая 2013

Что происходит, так это то, что экземпляр класса делегата освобождается (вызывая EXC_BAD_ACCESS в цикле выполнения) либо потому, что вы его не сохранили, либо вы используете ARC (весьма вероятно), и у вас нет ссылкик этому.

Решение состоит в том, чтобы либо вызвать retain в классе делегата, примерно так:

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

Или, если у вас включен ARC, создайте переменную экземпляра в классе, в котором вы размещаетеделегировать и хранить там ваш экземпляр соединения.Таким образом, ARC не освободит его, потому что экземпляр var считается ссылкой.

2 голосов
/ 27 февраля 2014

Если вы используете ARC, создайте потоки следующим образом:

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

Это должно предотвратить сбой. И имейте в виду, что если ваши потоки принадлежат отдельному потоку, а не основному потоку, это означает, что цикл выполнения необходимо вызывать вручную, используя метод run после открытия потоков.

1 голос
/ 18 июля 2011

Когда я поместил это в свой View Controller (а не в отдельный класс), он работал отлично.

0 голосов
/ 06 апреля 2013

У меня была похожая проблема, когда мое приложение зависало при обратном вызове -handleEvent с огромным числом streamEvent. Я решил ее, убедившись, что инициализирую объекты NSStream (вход и выход) И , открываю соединение с сервером в методе -init объекта NetworkClient, который планирует использовать мой VC.

0 голосов
/ 14 июля 2011

Попробуйте один раз,

NSInputStream * inputStream = objc_unretainedObject (readStream);

Может быть проблема с кастингом

...