在各种队列中运行多个NSTimer实例

时间:2013-05-02 07:56:21

标签: iphone ios

在iPhone App编码中,我需要并行完成几项任务:

第1部分:始终(即使应用程序当前未处于活动状态): 从远程数据库中获取一些数据并将其保存在本地Sqlite中 为此,我在AppDelegate的单独队列中触发NSTimer,如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    ...
    self.queueForDbFetch = dispatch_queue_create("queueForDbFetch", NULL);
    self.queueForDbFetchTimer = dispatch_queue_create("queueForDbFetchTimer", NULL);
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(getDbData:) name:kNotif_GetDbData object:nil];
    dispatch_async(self.queueForDbFetchTimer, ^(void) {
    self.timerDbNotifier = [NSTimer scheduledTimerWithTimeInterval:60.0
                                                target:self selector:@selector(scheduleNotificationToFetchDbData)
                                                userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timerDbNotifier forMode:NSDefaultRunLoopMode];
    });
    ...
    ...
}

第2部分:

然后,我需要使用获取的数据(来自本地sqlite数据库)异步更新UI,这与队列&在UIViewController类中这样的定时器(类似于上面的):

-(void) initializeThisView {

// Make sure the queues are created only once
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    self.queueForUiRefresh = dispatch_queue_create("queueForUiRefresh", NULL);
    self.queueForUiRefreshTimer = dispatch_queue_create("queueForUiRefreshTimer", NULL);
});
[self scheduleUiDataRefresher];
}

-(void) scheduleUiDataRefresher {

dispatch_async(self.queueForUiRefreshTimer, ^(void) {

    self.timerUiDataRefresh = [NSTimer scheduledTimerWithTimeInterval:60.0
                                       target:self selector:@selector(loadUiData)
                                     userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timerUiDataRefresh forMode:NSDefaultRunLoopMode];
});
}

-(void) loadUiData {

    dispatch_async(self.queueForUiRefresh, ^(void) {
        [self refreshWithUiData:dict];
    });
}

问题:

NSTimer实例(在第1部分和第2部分中)被触发一次,就是这样。他们不重复。 1.会创建NSTimer在主队列中重复其他用户与App的交互吗? 2.我的活动结构是否有任何问题(或更好的方法)?

1 个答案:

答案 0 :(得分:2)

不要在dispatch_async()调用中创建计时器。一旦传递给dispatch_async()的块已经完成运行(并且它在创建定时器后直接完成),所有属于它的数据都将被释放。我很惊讶它没有崩溃。此外,当您使用scheduledTimerWithTimeInterval:target:selector:userInfo:重复时,计时器将已安排到主runloop。对NSRunLoop:addTimer:的调用不是必需的,它将无效或者在调度计时器时会发生冲突。

回答你的问题:

创建没有dispatch_async()的计时器,只需直接调用NSTimer:scheduledTimerWithTimeInterval :.不要使用NSRunLoop:addTimer(除非你确切地知道为什么要这样)。然后在您的计时器调用的选择器中,使用dispatch_async()来启动异步任务。

但是,如果您确定这些任务不会花费很长时间,那么您也可以完全避免使用dispatch_async()。