Cocoa EXC_错误_指令:任务_线程失败

Cocoa EXC_错误_指令:任务_线程失败,cocoa,macos,sockets,Cocoa,Macos,Sockets,我正在编写一个应用程序来打印从服务器收到的消息。我在另一个线程中分离侦听功能: 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 ); perro

我正在编写一个应用程序来打印从服务器收到的消息。我在另一个线程中分离侦听功能:

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:
并收到标题中的错误时,应用程序崩溃。如果我对所有这些调用进行注释,应用程序工作正常,我可以在控制台中阅读正确的消息。
有什么建议吗?

辅助线程实际上不应该接触GUI。您需要将信息传递回主线程上的对象,并让该对象更新文本视图

从:

线程和用户界面
如果应用程序具有图形用户界面,建议您从应用程序的主线程接收与用户相关的事件并启动界面更新。此方法有助于避免与处理用户事件和图形窗口内容相关的同步问题。一些框架,比如Cocoa,通常需要这种行为,但即使对于那些不需要这种行为的框架,将这种行为保留在主线程上也具有简化用户界面管理逻辑的优势


辅助线程实际上不应该接触GUI。您需要将信息传递回主线程上的对象,并让该对象更新文本视图

从:

线程和用户界面
如果应用程序具有图形用户界面,建议您从应用程序的主线程接收与用户相关的事件并启动界面更新。此方法有助于避免与处理用户事件和图形窗口内容相关的同步问题。一些框架,比如Cocoa,通常需要这种行为,但即使对于那些不需要这种行为的框架,将这种行为保留在主线程上也具有简化用户界面管理逻辑的优势


我不确定这是否是问题的确切原因,但肯定可能是:您从未初始化
读取
,因此您无法预测地覆盖了程序内存中的某些字节。应该是这样的:

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];

尽管Josh Caswell指出,所有这些
insertText:
消息应该类似于
[messagesView PerformSelector OnMainThread:@selector(insertText:)with object:@“\n远程主机关闭的连接\n”延迟后:0]

我不确定这是否是问题的确切原因,但它确实可能是:您从未初始化
读取
,因此您无法预测地覆盖了程序内存中的某些字节。应该是这样的:

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];

尽管Josh Caswell指出,所有这些
insertText:
消息应该类似于
[messagesView PerformSelector OnMainThread:@selector(insertText:)with object:@“\n远程主机关闭的连接\n”延迟后:0]

是否使用Grand Central Dispatch?是否使用Grand Central Dispatch?