2011-07-13 8 views
8

Todos,NSStreams Programa de bloqueo!

Lo he bajado hasta este punto mediante comentarios, puntos de interrupción, etc. El programa se bloquea en el código marcado.

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

no choque si comento hacia fuera ambas cosas, pero se bloquea si comento hacia fuera uno (por lo tanto es decir, están causando el programa se bloquee). No hay información que se publique en el depurador tampoco. Todo lo que hace es enviarme a main.m y me muestran

"Tema 1: Programa de recepción de la señal: 'EXC_BAD_ACCESS'

Gracias por la ayuda de antemano

Editar: Aquí está mi delegar método, pero ni siquiera se presenta la segunda línea activa en el registro.

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

} 
+1

El subproceso 1 no es el subproceso principal. Probablemente esté siendo utilizado por las corrientes mientras se están abriendo. El bloqueo podría estar ocurriendo en el método 'stream: handleEvent:' de su delegado, por lo que le sugiero que comience allí. – ughoavgfhw

+1

Si se produce un bloqueo, hay una traza inversa. Publícalo. – bbum

+0

Se agregó algo de información. – Baub

Respuesta

1

Cuando hice esto en mi controlador de vista (y no en una clase separada) que funcionó a la perfección.

+0

eso significa que el objeto local no puede ser retenido. Excepto mover todo a UIVIewController, puede cuidar el objeto local como un iVar o propiedad del controlador de vista, haciendo eso, he logrado sacarlo de carshes :) –

-2

probar esto una vez,

NSInputStream * inputStream = objc_unretainedObject (readStream);

May be a casting issue

+3

Si se habilitó ARC, ese código no se compilaría como está escrito de todos modos. Esta respuesta no tiene sentido. – bbum

+0

oops .... puede que estuviera en ios5 streams en mi mente por completo ...No agregué todo esto: si la aplicación está en ios5 entonces ... mi mal ... como dijo bbum, esto se aplica solo en un entorno contado de referencia automática ... – Futur

0

Tuve un problema similar donde mi aplicación se bloqueaba en la devolución de llamada de handleEvent con un gran número de streamEvent. Lo resolví asegurándome de inicializar los objetos de NSStream (entrada y salida) Y abro una conexión al servidor en el método de entrada del objeto NetworkClient que mi VC planea usar.

4

Lo que está sucediendo es que la instancia de la clase de delegado se está desasignando (causando EXC_BAD_ACCESS en el ciclo de ejecución) ya sea porque no la retuvo, o porque está usando ARC (bastante probable) y no tiene una referencia a eso

La solución es o bien llamar a retener en la clase delegada, aproximadamente así:

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

O si tiene ARC habilitado, haga una variable de instancia en la clase en la que alloc el delegado, y almacenar su instancia de conexión allí. De esta forma, ARC no lo desasignará, porque la instancia var cuenta como referencia.

2

Si está utilizando ARC, echados los flujos de la siguiente manera:

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

Esto debería evitar el accidente. Y tenga en cuenta que si sus flujos son propiedad de un hilo separado del hilo principal, esto significa que el ciclo de ejecución debe llamarse manualmente utilizando el método run después de abrir los flujos.

+0

Esta es una respuesta mejor y más precisa – xaphod