NSThread的启动流程

image.png
参考GNU的代码实现
+ (void) detachNewThreadSelector: (SEL)aSelector
                toTarget: (id)aTarget
                      withObject: (id)anArgument
{
  NSThread  *thread;
  /*
   * Create the new thread.
   */
  thread = [[NSThread alloc] initWithTarget: aTarget
                                   selector: aSelector
                                     object: anArgument];
  [thread start];
  RELEASE(thread);
}
- (id) initWithTarget: (id)aTarget
             selector: (SEL)aSelector
               object: (id)anArgument
{
  /* initialize our ivars. */
  _selector = aSelector;
  _target = RETAIN(aTarget);
  _arg = RETAIN(anArgument);
  init_autorelease_thread_vars(&_autorelease_vars);
  return self;
}
- (void) start
{
  pthread_attr_t    attr;
  pthread_t     thr;

  if (_active == YES)
    {
      [NSException raise: NSInternalInconsistencyException
                  format: @"[%@-%@] called on active thread",
        NSStringFromClass([self class]),
        NSStringFromSelector(_cmd)];
    }
  if (_cancelled == YES)
    {
      [NSException raise: NSInternalInconsistencyException
                  format: @"[%@-%@] called on cancelled thread",
        NSStringFromClass([self class]),
        NSStringFromSelector(_cmd)];
    }
  if (_finished == YES)
    {
      [NSException raise: NSInternalInconsistencyException
                  format: @"[%@-%@] called on finished thread",
        NSStringFromClass([self class]),
        NSStringFromSelector(_cmd)];
    }

  /* Make sure the notification is posted BEFORE the new thread starts.
   */
  gnustep_base_thread_callback();

  /* The thread must persist until it finishes executing.
   */
  RETAIN(self);

  /* Mark the thread as active whiul it's running.
   */
  _active = YES;

  errno = 0;
  pthread_attr_init(&attr);
  /* Create this thread detached, because we never use the return state from
   * threads.
   */
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  /* Set the stack size when the thread is created.  Unlike the old setrlimit
   * code, this actually works.
   */
  if (_stackSize > 0)
    {
      pthread_attr_setstacksize(&attr, _stackSize);
    }
  if (pthread_create(&thr, &attr, nsthreadLauncher, self))
    {
      DESTROY(self);
      [NSException raise: NSInternalInconsistencyException
                  format: @"Unable to detach thread (last error %@)",
                  [NSError _last]];
    }
}
- (void) main
{
  if (_active == NO)
    {
      [NSException raise: NSInternalInconsistencyException
                  format: @"[%@-%@] called on inactive thread",
        NSStringFromClass([self class]),
        NSStringFromSelector(_cmd)];
    }

  [_target performSelector: _selector withObject: _arg];
}
+ (void) exit
{
  NSThread  *t;

  t = GSCurrentThread();
  if (t->_active == YES)
    {
      unregisterActiveThread(t);

      if (t == defaultThread || defaultThread == nil)
    {
      /* For the default thread, we exit the process.
       */
      exit(0);
    }
      else
    {
          pthread_exit(NULL);
    }
    }
}

你可能感兴趣的:(NSThread的启动流程)