is there a way to pause an NSTHread indefinitely and have it resumed from another thread?

前端 未结 3 880
广开言路
广开言路 2021-02-09 23:58

Seems these are the only methods to put a NSThread to sleep

* sleepForTimeInterval:

* sleepUntilDate:

Would it be bad practice what I am aski

3条回答
  •  忘掉有多难
    2021-02-10 00:18

    Do you want your thread to just stop until some other thread tells it to start up again? If so, you could use an NSConditionLock. An NSConditionLock is similar to a condition variable. It has a couple of basic methods, lockWhenCondition, and unlockWithCondition, and lock. A typical usage is to have your background thread waiting on the condition lock with "lockWhenCondition:", and the in you foreground thread to set the condition, which causes the background thread to wake up. The condition is a simple integer, usually an enumeration.

    Here's an example:

    enum {
        kWorkTodo = 1,
        kNoWorkTodo = 0
    }
    
    - (id)init {
        if ((self = [super init])) {
            theConditionLock = [[NSCoditionLock alloc] initWithCondition: kNoWorkTodo];
            workItems = [[NSMutableArray alloc] init];
        }
    }
    
    - (void)startDoingWork {
        [NSThread detachNewThreadSelector:@selector(doBackgroundWork) toTarget:self withObject:nil];
    }
    
    - (void)doBackgroundWork:(id)arg {
        while (YES) {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
            NSArray *items = nil;
            [theConditionLock lockWhenCondition:kWorkTodo]; // Wait until there is work to do
            items = [NSArray arrayWithArray:workItems]
            [workItems removeAllObjects];
            [theConditionLock unlockWithCondition:kNoWorkTodo];
            for(id item in items) {
                // Do some work on item.
            }
            [pool drain];
        }
    }
    
    - (void)notifyBackgroundThreadAboutNewWork {
        [theConditionLock lock];
        [workItems addObject:/* some unit of work */];
        [theConditionLock unlockWithCondition:kWorkTodo];
    }
    

    In this example, when startDoingWork is called doBackgroundWork: will start on a background thread, but then stop because there isn't any work to do. Once notifyBackgroundThreadAboutNewWork is called, then doBackgroundWork: will fire up and process the new work, and then go back to sleep waiting for new work to be available, which will happen the next time notifyBackgroundThreadAboutNewWork is called.

提交回复
热议问题