2011-04-18 48 views
0

我正在編寫一個應用程序來打印從服務器收到的消息。我分開在不同的線程的聆聽功能:EXC_BAD_INSTRUCTION:task_thread失敗可可

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
char *read; 

do { 
    chk = (int) recv(connfd, read, 1, 0); 

    if(chk==-1) { 
     printf("Error in recv(): connfd = %d\n",connfd); 
     perror(err); 
    } 
    else if (chk ==0) { 
     [messagesView insertText:@"\nConnection closed by remote host\n"]; 
     printf("Connection closed by remote host\n"); 
    } 
    else { 
     if(*read == '\n') { 
      [messagesView insertText:@"\\n\n"]; 
      printf("\\n"); 
     } 
     else if (*read == '\r') { 
      [messagesView insertText:@"\\r\r"]; 
      printf("\\r"); 
     } 
     else { 
      [messagesView insertText:[NSString stringWithFormat:@"%c",*read]]; 
      printf("%c", *read); 
     } 
     printf(" -- %d\n",*read); 
    } 
} while (chk>0); 

[pool drain]; 

chk和connfd是int,messagesView是一個NSTextView *。 當我呼叫[messagesView insertText:]時,應用程序崩潰,並且我收到標題中的錯誤。如果我評論所有這些調用,應用程序工作正常,我可以在控制檯中閱讀正確的消息。 有什麼建議嗎?

+0

您是否使用Grand Central Dispatch? – 2011-04-18 18:21:57

回答

4

輔助線程不是真的應該觸及GUI。您需要將信息傳遞迴主線程上的對象並更新文本視圖。

Threading Programming Guide

線程和用戶界面
如果您的應用程序有一個圖形用戶界面,則建議您從應用程序的主接收用戶相關的事件,並啓動界面更新線。這種方法有助於避免與處理用戶事件和繪製窗口內容相關的同步問題。一些框架,比如Cocoa,通常需要這種行爲,但即使對於那些不這樣做的行爲,在主線程上保持這種行爲的優點是簡化了管理用戶界面的邏輯。

+0

謝謝,看來是錯誤! – alfred 2011-04-19 13:09:43

2

我不知道,如果這是你的問題的確切原因,但可以肯定的可能是:你永遠不會初始化read,所以你無法預測在改寫你的程序內存的字節。它應該是這樣的:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
char read; 

do { 
    chk = (int) recv(connfd, &read, 1, 0); 

    if(chk==-1) { 
     printf("Error in recv(): connfd = %d\n",connfd); 
     perror(err); 
    } 
    else if (chk ==0) { 
     [messagesView insertText:@"\nConnection closed by remote host\n"]; 
     printf("Connection closed by remote host\n"); 
    } 
    else { 
     if(read == '\n') { 
      [messagesView insertText:@"\\n\n"]; 
      printf("\\n"); 
     } 
     else if (read == '\r') { 
      [messagesView insertText:@"\\r\r"]; 
      printf("\\r"); 
     } 
     else { 
      [messagesView insertText:[NSString stringWithFormat:@"%c", read]]; 
      printf("%c", read); 
     } 
     printf(" -- %d\n", read); 
    } 
} while (chk>0); 

[pool drain]; 

雖然作爲喬希卡斯威爾指出,所有這些insertText:的消息應該是這樣[messagesView performSelectorOnMainThread:@selector(insertText:) withObject:@"\nConnection closed by remote host\n" afterDelay:0]

+0

用於'performSelectorOnMainThread' – Saphrosit 2012-03-21 12:59:57