0

在 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 DB)异步更新 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. 我的活动结构有什么问题(或更好的方法)吗?

4

1 回答 1

2

Don't create the timers in the dispatch_async() call. As soon as the block you pass to dispatch_async() has finished running (and it finishes directly after creating the timer), all data belonging to it is freed. I'm surprised it doesn't crash. Also, when you use scheduledTimerWithTimeInterval:target:selector:userInfo:repeats, the timer will already be scheduled to the main runloop. The call to NSRunLoop:addTimer: is not necessary, it will either have no effect or you will have a conflict in scheduling the timer.

To answer your questions:

Create the timers without dispatch_async(), just call NSTimer:scheduledTimerWithTimeInterval: directly. Do not use NSRunLoop:addTimer (unless you know exactly why you want it that way). Then in the selector that is being called by your timers, use dispatch_async() to fire off your asynchronous tasks.

However, if you are sure that these tasks do not take long, you might as well avoid using dispatch_async() altogether.

于 2013-05-02T08:08:51.543 回答