2011-07-13 128 views
8

全部,NSStreams崩溃程序!

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

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

} 
+1

线程1不是主线程。它可能正在被这些溪流在开放时使用。崩溃可能发生在你的委托的'stream:handleEvent:'方法中,所以我会建议从那里开始。 – ughoavgfhw

+1

如果发生崩溃,则会出现回溯。发表它。 – bbum

+0

添加了一些信息。 – Baub

回答

1

当我(而不是在一个单独的类)放在这在我的视图控制器,它的工作完美。

+0

这意味着,本地对象不能保留。除了把整个东西移动到UIVIewController,你可以删除本地对象作为iVar或视图控制器的属性,这样做,我已经设法拉出车轮:) –

-2

试试这个出一次,

NSInputStream * inputStream = objc_unretainedObject(readStream);

May be a casting issue

+3

如果启用了ARC,那么该代码不会按照书面方式进行编译。这个答案没有意义。 – bbum

+0

oops ....可能是我在ios5流中完全在我脑海里..我没有补充说:如果应用程序是在ios5然后 ..我的坏..因为bbum说,这只适用于自动引用计数环境.. – Futur

0

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

4

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

的解决方法是调用保留在委托类,大约像这样:

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

或者如果你有ARC启用,使一个实例变量在您的Alloc委托类和存储你在那里的连接实例。这样ARC就不会解除它的分配,因为实例变量var作为参考。

2

如果使用ARC,铸流是这样的:

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

这应该防止死机。并且请记住,如果您的流属于独立线程而不是主线程,那意味着在打开流之后需要使用run方法手动调用运行循环。

+0

这是一个更好,更准确的答案 – xaphod