换句话说,如果我有一个持续运行的进程,但用户可以在 GUI 上更改影响进程操作特性的参数,那么将进程放在哪里更好NSThread
?NSTimer
问问题
907 次
2 回答
1
NSThread 和 NSTimer 不是相互排斥的,也不是相互替代的。NSThread 允许您控制执行线程,而 NSTimer 就是一个计时器。
我假设您的意思是在后台线程而不是在主线程上运行 NSTimer?这通常是一个好主意,这样计时器就不太可能被主线程上发生的事情(例如用户与应用程序的交互)延迟。
您应该阅读Apple 的线程编程指南。
于 2012-05-14T15:11:47.353 回答
1
虽然NSThread
和NSTimer
是针对不同需求的两个独立事物,但让我们比较这两个功能:
使用NSThread
:
-(void) doSomethingEverySecond {
__block int cumValue = 0; // cumulative value
__block void(^execBlock)() = ^{
while (1)
{
@try
{
// some code here that might either A: call continue to continue the loop,
// or B: throw an exception.
cumValue++;
NSLog(@"Cumulative Value is: %i", cumValue);
if (cumValue == 5)
return;
}
@finally
{
[NSThread sleepForTimeInterval:1];
}
}
};
[NSThread detachNewThreadSelector:@selector(invoke) toTarget:[execBlock copy] withObject:nil];
}
使用NSTimer
:
-(void) doSomethingEverySecond {
__block NSTimer *timer = nil;
__block int cumValue = 0;
__block void (^execBlock)() = ^{
cumValue++;
NSLog(@"Cumulative Value is: %i", cumValue);
if (cumValue == 5)
[timer invalidate];
};
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:[execBlock copy] selector:@selector(invoke) userInfo:nil repeats:YES];
}
现在,如果我们只想要一次,NSThread
就是要走的路,如下所示:
-(void) doSomethingOnce {
__block void (^execBlock)() = ^{
NSLog(@"Doing something that could take a LONG time!");
};
[NSThread detachNewThreadSelector:@selector(invoke) toTarget:[execBlock copy] withObject:nil];
}
现在,对于NSTimer
变体:
-(void) doSomethingOnce {
__block void (^execBlock)() = ^{
NSLog(@"Doing something that could take a LONG time!");
};
[NSTimer scheduledTimerWithTimeInterval:0 target:[execBlock copy] selector:@selector(invoke) userInfo:nil repeats:NO];
}
这样做的原因是我们在使用 a 时可以完全控制线程NSThread
,但如果使用 a NSTimer
,我们会在 a 内部执行NSRunLoop
,如果在内部完成任何繁重的工作,可能会冻结 UI。这就是 aNSThread
比 a的优势NSTimer
。
您还可以保证NSThread
被分离的 a 会立即执行NSTimer
,而基于 NSRunLoop 的 a 不能,因为它可能会也可能不会立即执行。
还有第三种选择(从技术上讲也是第四种,pthread
s,但我现在暂时忽略它)GCD
,但我建议你使用 RTFM,因为它的主题太宽泛,无法在这篇文章中涵盖。
于 2012-05-14T15:30:35.040 回答