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」。

よろしくお願いします!

編集:これが私のデリゲートメソッドですが、ログに2番目のアクティブな行も表示されません。

- (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を使用していて(おそらく)参照がないためです。

解決策は、ほぼ次のように、デリゲートクラスでretainを呼び出すことです。

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

または、ARCを有効にしている場合は、デリゲートを割り当てるクラスでインスタンス変数を作成し、そこに接続のインスタンスを保存します。そうすれば、インスタンスvarが参照としてカウントされるため、ARCはそれを割り当て解除しません。

于 2013-05-27T15:52:09.740 に答える
2

ARCを使用している場合は、次のようにストリームをキャストします。

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

これにより、クラッシュを防ぐことができます。また、ストリームがメインスレッドとは別のスレッドによって所有されている場合は、ストリームを開いた後、runメソッドを使用してrunループを手動で呼び出す必要があることに注意してください。

于 2014-02-27T08:26:14.813 に答える
1

これをViewControllerに(別のクラスではなく)配置すると、完全に機能しました。

于 2011-07-18T16:21:43.473 に答える
0

同様の問題が発生し、巨大なstreamEvent番号を使用して-handleEventコールバックでアプリがクラッシュしました。NSStreamオブジェクト(入力と出力)を初期化し、VCが使用する予定のNetworkClientオブジェクトの-initメソッドでサーバーへの接続を開くことで問題を解決しました。

于 2013-04-06T19:48:18.967 に答える
-2

これを一度試してみてください

NSInputStream * inputStream = objc_unretainedObject(readStream);

キャスティングの問題である可能性があります

于 2011-07-14T09:20:42.953 に答える