2011-04-18 53 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