看起来这些是使NSThread休眠的唯一方法
* sleepForTimeInterval:
* sleepUntilDate:
这样问是否不好的做法?
看起来这些是使NSThread休眠的唯一方法
* sleepForTimeInterval:
* sleepUntilDate:
如果您希望您的线程一直停止,直到其他线程告诉它再次启动,那么您可以使用NSConditionLock。 NSConditionLock类似于条件变量,具有一些基本方法:lockWhenCondition、unlockWithCondition和lock。典型用法是在后台线程上使用“lockWhenCondition:”等待条件锁,而在前台线程中设置条件,这会导致后台线程醒来。条件是一个简单的整数,通常是枚举。
以下是示例:
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];
}
在这个例子中,当调用startDoingWork时,doBackgroundWork:会在后台线程上启动,但由于没有工作要做,它会立即停止。一旦调用notifyBackgroundThreadAboutNewWork,然后doBackgroundWork:将启动并处理新的工作,然后回到休眠状态等待新的工作可用,这将在下次调用notifyBackgroundThreadAboutNewWork时发生。workItems
数组是一个收件箱;notifyBackgroundThreadAboutNewWork
方法将新项留在其中,而在lockWithCondition:
和unlockWithCondition:
消息之间的代码将这些项提取到一个新数组(items
)中。所有真正的工作都发生在unlockWithCondition:
之后,并且使用该临时items
数组。 - Peter HoseylockWhenCondition
调用有效地导致后台线程“无限期”休眠(正如您所说),直到前台线程指定满足了条件。至于NSLock和NSConditionLock之间的区别,如果您阅读文档,那么这显然是非常明显的。使用NSLock,每个人都在同一件事上锁定。条件锁可以指定N个不同的条件,这允许更精细的锁定。 - Quinn Taylor你想做什么并不清楚。停止线程并在新线程上恢复相同的函数?(这是毫无意义的——旧线程有什么问题吗?)停止线程并在另一个现有线程上恢复相同的函数?
无论哪种方式,都不可能,也不是一个好主意。正确的解决方案是将您的函数分成两个部分,然后使用一些或所有运行循环、NSTimer、performSelector…
方法和NSPort来实现您想要做的任何事情。
如果您设想的黑暗线程魔法没有发生,您的程序将工作得更好。