2011-07-13 124 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