开发者

EXC_BAD_INSTRUCTION : task_thread failed cocoa

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 NSTextV开发者_StackOverflow中文版iew*. 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?


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜