我的NSTimer
定义如下:
timer = [NSTimer scheduledTimerWithTimeInterval:30
target:self
selector:@selector(fooBar)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
我希望它在这种情况下使用后台线程调用回调函数fooBar
。但是当我用if ([NSThread mainThread])
检查时,我总是在主线程上获取它。除了从回调函数调度线程之外还有其他方法吗?
答案 0 :(得分:3)
您正在将计时器添加到主线程。您的回电也将在主线程中。要在后台线程中安排计时器,我认为您需要使用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
答案 1 :(得分:0)
如果要在后台线程上运行计时器,最有效的方法是使用调度计时器:
@property (nonatomic, strong) dispatch_source_t timer;
然后您可以将此计时器配置为每两秒触发一次:
- (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;
}