在iOS应用程序中使用dispatch_source_t无法在GCD块中运行计时器

我想在GCD块中创建一个定时器(它将每2秒触发一次并调用一个方法)来将其用作后台任务.但是,当我看到定时器火从来没有.这是我的代码
- (void)startMessaging
{
    BOOL queue = YES;
    dispatch_queue_t _queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0);
    dispatch_source_t timerSource = dispatch_source_create(disPATCH_SOURCE_TYPE_TIMER,_queue);
    dispatch_source_set_timer(timerSource,dispatch_walltime(NULL,0),2ull * NSEC_PER_SEC,1ull * NSEC_PER_SEC );
    dispatch_source_set_event_handler(timerSource,^{
        if (queue) {
            [self observeNewMsgs];
        }
    });
    dispatch_resume(timerSource);
}

- (void)observeNewMsgs
{
    NSLog(@"JUST TO TEST");
    // Staff code...
}

那么这是什么问题?如何解决这个问题?

解决方法

您必须使您的dispatch_source_t成为一个属性或实例变量,因此它不会超出范围(因为在ARC中,当它落在范围之外时,它将被释放).如果你这样做,你的代码可以正常工作,例如:
@interface ViewController ()
@property (nonatomic,strong) dispatch_source_t timerSource;
@property (getter = isObservingMessages) BOOL observingMessages;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self startMessaging];
}

- (void)startMessaging
{
    self.observingMessages = YES;
    dispatch_queue_t queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0);
    self.timerSource = dispatch_source_create(disPATCH_SOURCE_TYPE_TIMER,queue);
    dispatch_source_set_timer(self.timerSource,1ull * NSEC_PER_SEC);
    dispatch_source_set_event_handler(self.timerSource,^{
        if (self.isObservingMessages) {
            [self observeNewMsgs];
        }
    });
    dispatch_resume(self.timerSource);
}

- (void)observeNewMsgs
{
    NSLog(@"JUST TO TEST");
    // Staff code...
}

@end

另请注意,如果您希望在启动后台进程后更改BOOL的值,您可能也希望将其设置为类属性,如上所示.我也将其更名为观察消息,使其目的更为简单.

(它只是风格,但我只使用下划线字符的类实例变量,所以我将你的_queue变量重命名为队列.)

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...