1

换句话说,如果我有一个持续运行的进程,但用户可以在 GUI 上更改影响进程操作特性的参数,那么将进程放在哪里更好NSThreadNSTimer

4

2 回答 2

1

NSThread 和 NSTimer 不是相互排斥的,也不是相互替代的。NSThread 允许您控制执行线程,而 NSTimer 就是一个计时器。

我假设您的意思是在后台线程而不是在主线程上运行 NSTimer?这通常是一个好主意,这样计时器就不太可能被主线程上发生的事情(例如用户与应用程序的交互)延迟。

您应该阅读Apple 的线程编程指南

于 2012-05-14T15:11:47.353 回答
1

虽然NSThreadNSTimer是针对不同需求的两个独立事物,但让我们比较这两个功能:

使用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 不能,因为它可能会也可能不会立即执行。

还有第三种选择(从技术上讲也是第四种,pthreads,但我现在暂时忽略它)GCD,但我建议你使用 RTFM,因为它的主题太宽泛,无法在这篇文章中涵盖。

于 2012-05-14T15:30:35.040 回答