Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1049831
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T16:40:40+00:00 2026-05-16T16:40:40+00:00

When I use pthread in cocoa, and want to access cocoa control in pthread

  • 0

When I use pthread in cocoa, and want to access cocoa control in pthread function(setBtnState), it doesn’t work. What’s the problem?

The following is the source code:

AppController.h

 1  //
 2  //  AppController.h
 3  //  PThreadTest
 4  //
 5  //  Created by zhu on 10-9-5.
 6  //  Copyright 2010 __MyCompanyName__. All rights reserved.
 7  //
 8  
 9  #import <Cocoa/Cocoa.h>
10  
11  
12  @interface AppController : NSObject {
13      IBOutlet NSButton *btnNew;
14      IBOutlet NSButton *btnEnd;
15  }
16  
17  -(IBAction)newThread:(id)sender;
18  -(IBAction)endThread:(id)sender;
19  
20  @end

AppController.m

 1  //
 2  //  AppController.m
 3  //  PThreadTest
 4  //
 5  //  Created by zhu on 10-9-5.
 6  //  Copyright 2010 __MyCompanyName__. All rights reserved.
 7  //
 8  
 9  #import "AppController.h"
10  #import <pthread.h>
11  
12  
13  @implementation AppController
14  
15  struct mydata {
16      pthread_mutex_t mutex;
17      pthread_cond_t cond;
18      int stop;
19      NSButton *btnNew;
20      NSButton *btnEnd;
21  };
22  
23  struct mydata adata;
24  struct mydata *ptr;
25  
26  void setBtnState(struct mydata *p) {
27      BOOL stop = NO;
28      if (p->stop) {
29          stop = YES;
30      }
31      [p->btnNew setEnabled:stop];
32      [p->btnEnd setEnabled:!stop];
33  }
34  
35  void* mythread(void* arg) {
36      NSLog(@"new thread start...");
37      ptr->stop = 0;
38      setBtnState(ptr);
39      pthread_mutex_lock(&ptr->mutex);
40      while (!ptr->stop) {
41          pthread_cond_wait(&ptr->cond, &ptr->mutex);
42      }
43      pthread_mutex_unlock(&ptr->mutex);
44      setBtnState(ptr);
45      NSLog(@"current thread end...");
46  }
47  
48  -(id)init {
49      self = [super init];
50      ptr = &adata;
51      pthread_mutex_init(&ptr->mutex, NULL);
52      pthread_cond_init(&ptr->cond, NULL);
53      ptr->stop = 0;
54      ptr->btnNew = btnNew;
55      ptr->btnEnd = btnEnd;
56      return self;
57  }
58  
59  -(IBAction)newThread:(id)sender {
60      pthread_t pid;
61      pthread_create(&pid, NULL, mythread, NULL);
62  }
63  
64  -(IBAction)endThread:(id)sender {
65      pthread_mutex_lock(&ptr->mutex);
66      ptr->stop = 1;
67      pthread_mutex_unlock(&ptr->mutex);
68      pthread_cond_signal(&ptr->cond);
69  }
70  
71  @end

Thanks to Chris. In the backgroud thread in order to update control’s state I use performSelectorOnMainThread to communicate with the main UI thread.

But when btnEnd is pressed, the debugger console show the following infomation:

2010-09-12 23:36:29.255 PThreadTest[1888:a0f] -[AppController setBtnState]: unrecognized selector sent to instance 0x100133030

Why it doesn’t work after I updated AppController.m as the following:

 1  //
 2  //  AppController.m
 3  //  PThreadTest
 4  //
 5  //  Created by zhu on 10-9-5.
 6  //  Copyright 2010 __MyCompanyName__. All rights reserved.
 7  //
 8  
 9  #import "AppController.h"
10  #import <pthread.h>
11  
12  
13  @implementation AppController
14  
15  struct mydata {
16      pthread_mutex_t mutex;
17      pthread_cond_t cond;
18      int stop;
19      NSButton *btnNew;
20      NSButton *btnEnd;
21      id obj;
22  };
23  
24  struct mydata adata;
25  struct mydata *ptr;
26  
27  void* mythread(void* arg) {
28      NSLog(@"new thread start...");
29      ptr->stop = 0;
30      pthread_mutex_lock(&ptr->mutex);
31      while (!ptr->stop) {
32          pthread_cond_wait(&ptr->cond, &ptr->mutex);
33      }
34      pthread_mutex_unlock(&ptr->mutex);
35      [ptr->obj performSelectorOnMainThread:@selector(setBtnState) withObject:@"YES" waitUntilDone:NO];
36      NSLog(@"current thread end...");
37  }
38  
39  -(void)setBtnState:(id)aobj {
40      BOOL stop = NO;
41      if ([aobj isEqualToString:@"YES"]) {
42          stop = YES;
43      }
44      [btnNew setEnabled:stop];
45      [btnEnd setEnabled:!stop];
46  }
47  
48  -(id)init {
49      self = [super init];
50      ptr = &adata;
51      pthread_mutex_init(&ptr->mutex, NULL);
52      pthread_cond_init(&ptr->cond, NULL);
53      ptr->stop = 0;
54      ptr->obj = self;
55      //  ptr->btnNew = btnNew;
56      //  ptr->btnEnd = btnEnd;
57      return self;
58  }
59  
60  - (void)awakeFromNib {
61      ptr->btnNew = btnNew;
62      ptr->btnEnd = btnEnd;
63  }
64  
65  -(IBAction)newThread:(id)sender {
66      [self setBtnState:@"NO"];
67      pthread_t pid;
68      pthread_create(&pid, NULL, mythread, NULL);
69  }
70  
71  -(IBAction)endThread:(id)sender {
72      pthread_mutex_lock(&ptr->mutex);
73      ptr->stop = 1;
74      pthread_mutex_unlock(&ptr->mutex);
75      pthread_cond_signal(&ptr->cond);
76  }
77  
78  @end
79  
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T16:40:41+00:00Added an answer on May 16, 2026 at 4:40 pm

    You should only interact with your UI from the main thread, not from background threads.

    This isn’t just a matter of locking around interaction with your own controls; your controls may interact with other objects in the UI behind your back. (For example, your button may interact with your window.) This can lead to race conditions, deadlocks, invalid/mixed state, and other concurrency problems.

    When you’re doing some processing work on a background thread, and it needs to communicate results (whether intermediate or final) to the user, it will need to push that communication through the main thread. There are a few mechanisms in Cocoa with which to do this:

    1. The -performSelectorOnMainThread:withObject:waitUntilDone: method lets you say “run this other method on the main thread,” optionally waiting until it’s done. You should almost never pass YES for the waitUntilDone: argument though, as that’s a recipe for deadlock.

    2. Starting in Mac OS X 10.6 and iOS 4.0, there is +[NSOperationQueue mainQueue], which returns an instance of NSOperationQueue associated with the main thread: You can place operations on this queue and they will run on the main thread.

      This is useful if you’re using several operations on a background queue and you have some “finishing” operation to perform on the main thread that depends on all of them. You can just use NSOperation’s dependency mechanism to set up dependencies between them even though they’re on different queues.

      You can either subclass NSOperation or use Objective-C blocks for the bodies of your operations (via +[NSBlockOperation blockOperationWithBock:]).

    3. Also starting in Mac OS X 10.6 and iOS 4.0, there is Grand Central Dispatch which lets you perform a block on a main queue associated with the main thread. It’s a slightly less verbose API than NSOperation, but at the cost of not having direct support for dependencies and some of the other features of NSOperationQueue, and of being built in plain C rather than in Objective-C.

    One thing to remember when using any of these mechanisms is that you must not interact with the same data from multiple threads at the same time without appropriate concurrency control (such as locking, or the use of specialized lock-free data structures and primitives). You can’t get away with “Oh, I’m just reading, so I don’t need to take a lock,” or “Oh, I just need to enable a button, I don’t really need to push that to the main thread.”

    A good way to avoid this issue is to do as much work as possible by batching it up into discrete units, processing those units in the background, and then relaying the results to the main thread.

    So your threaded code is not written like this:

    • spin off a thread to:
      • lock the document
      • get some data from the document
      • unlock the document
      • process the data
      • tell the main thread whether to enable or disable the document’s Foo button

    Instead your threaded code is written like this:

    • get some data from the document
    • spin off a thread to:
      • process the data
      • then tell the main thread the result of the processing
    • on the main thread:
      • determine from the result of the processing whether to enable or disable the document’s Foo button

    The difference is that the latter is written in terms of the units of work being done, rather than in terms of the user interface, and will be both easier to understand and more robust in the face of your application’s life (such as adding features) – it’s essentially “MVC applied to threads.”

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I use the VS2008 command prompt for builds, TFS access etc. and the cygwin
'''use Jython''' import shutil print dir(shutil) There is no, shutil.move, how does one move
Use case: A does something on his box and gots stuck. He asks B
Use case: 3rd party application wants to programatically monitor a text file being generated
We use a data acquisition card to take readings from a device that increases
I use Firebug and the Mozilla JS console heavily, but every now and then
I use rsync to synchronize files to Windows clients in a server agnostic way.
I use emacs to edit my xml files (nxml-mode) and the files were generated
I use a stream reader to import some data and at the moment I
We use QuickBooks for financial management, and feed it from a variety of sources.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.