EXC_BAD_INSTRUCTION :任务线程失败可可

发布于 2024-11-02 02:42:50 字数 1087 浏览 0 评论 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];

chk 和 connfd 是 int,messagesView 是 NSTextView*。 当我调用 [messagesView insertText:] 时,应用程序崩溃,并且我收到标题中的错误。如果我评论所有这些调用,则应用程序可以正常工作,并且我可以在控制台中读取正确的消息。 有什么建议吗?

I'm writing an application to print messages received from a server. I detach in a different thread the listening function:

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 and connfd are int, messagesView is a NSTextView*.
The application crashes when I call [messagesView insertText:] and I receive the error in title. If I comment all these calls the application works fine and I can read the right message in the console.
Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨落星ぅ辰 2024-11-09 02:42:50

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

来自线程编程指南

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

Secondary threads aren't really supposed to touch the GUI. You'll need to pass the information back to an object on the main thread and have that update the text view.

From the Threading Programming Guide:

Threads and Your User Interface
If your application has a graphical user interface, it is recommended that you receive user-related events and initiate interface updates from your application’s main thread. This approach helps avoid synchronization issues associated with handling user events and drawing window content. Some frameworks, such as Cocoa, generally require this behavior, but even for those that do not, keeping this behavior on the main thread has the advantage of simplifying the logic for managing your user interface.

叶落知秋 2024-11-09 02:42:50

我不确定这是否是您问题的确切原因,但肯定可能是:您从未初始化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];

尽管正如 Josh Caswell 指出的那样,所有这些 insertText: 消息都应该类似于 [messagesView PerformSelectorOnMainThread:@selector(insertText:) withObject:@"\nConnection returned by远程主机\n" afterDelay:0]

I'm not sure if this is the precise cause of your problem, but it certainly could be: You never initialize read, so you're unpredictably overwriting some byte in your program's memory. It should be something like:

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

Though as Josh Caswell points out, all those insertText: messages should be something like [messagesView performSelectorOnMainThread:@selector(insertText:) withObject:@"\nConnection closed by remote host\n" afterDelay:0].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文