0

コーディング中の iPhone アプリでは、複数のタスクを並行して実行する必要があります。

パート 1: 常に (アプリが現在アクティブでない場合でも): リモート DB から一部のデータをフェッチし、ローカル 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 回起動され、それだけです。彼らは繰り返さない。1. メイン キューで繰り返す NSTimer を作成すると、他のユーザーによるアプリとのやり取りがブロックされますか? 2. 活動の構成に何か問題 (またはより良い方法) はありますか?

4

1 に答える 1

2

dispatch_async() 呼び出しでタイマーを作成しないでください。dispatch_async() に渡すブロックの実行が終了すると (そしてタイマーの作成直後に終了すると)、それに属するすべてのデータが解放されます。崩れないことに驚きです。また、scheduledTimerWithTimeInterval:target:selector:userInfo:repeats を使用すると、タイマーはすでにメインの実行ループにスケジュールされています。NSRunLoop:addTimer: への呼び出しは必要ありません。効果がないか、タイマーのスケジュールに競合が発生します。

質問に答えるには:

NSTimer:scheduledTimerWithTimeInterval: を直接呼び出すだけで、dispatch_async() を使用せずにタイマーを作成します。NSRunLoop:addTimer を使用しないでください (そのようにしたい理由が正確にわかっている場合を除きます)。次に、タイマーによって呼び出されているセレクターで、dispatch_async() を使用して非同期タスクを起動します。

ただし、これらのタスクに時間がかからないことが確実な場合は、dispatch_async() をまったく使用しない方がよいでしょう。

于 2013-05-02T08:08:51.543 に答える