1

我有一个NSTimer定义如下:

timer = [NSTimer scheduledTimerWithTimeInterval:30
                                         target:self
                                       selector:@selector(fooBar)
                                       userInfo:nil
                                        repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

fooBar在这种情况下,我希望它使用后台线程调用回调函数。但是当我检查时,if ([NSThread mainThread])总是在主线程上得到它。除了从回调函数中分派线程之外,还有其他方法吗?

4

2 回答 2

4

您正在将计时器添加到主线程。您的回调也将在主线程中。要在后台线程中安排计时器,我认为您需要使用 NSOperation 子类并从操作的main方法内部将计时器安排到 [NSRunLoop currentRunLoop] 。

#import <Foundation/Foundation.h>

@interface BackgroundTimer : NSOperation
{
    BOOL _done;
}
@end



#import "BackgroundTimer.h"

@implementation BackgroundTimer

-(void) main
{
    if ([self isCancelled])
    {
        return;
    }

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30
                                             target:self
                                           selector:@selector(fooBar)
                                           userInfo:nil
                                            repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

    //keep the runloop going as long as needed
    while (!_done && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                              beforeDate:[NSDate distantFuture]]);

}

@end
于 2013-03-29T20:50:35.547 回答
0

如果要在后台线程上运行计时器,最有效的方法是使用调度计时器:

@property (nonatomic, strong) dispatch_source_t timer;

and you can then configure this timer to fire every two seconds:

- (void)startTimer {
    dispatch_queue_t queue = dispatch_queue_create("com.domain.app.timer", 0);
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, 0), 2.0 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(self.timer, ^{
        // call whatever you want here
    });
    dispatch_resume(self.timer);
}

- (void)stopTimer {
    dispatch_cancel(self.timer);
    self.timer = nil;
}
于 2018-04-15T17:13:42.723 回答