web-dev-qa-db-ja.com

iOSで定期的にバックグラウンドスレッドでタスクを実行する

私はiOSの初心者です。メインスレッドでUIをロックしたくないので、バックグラウンドスレッドでサーバーからデータを取得するタスクを実行する必要があるアプリで作業しています。このタスクには時間がかかります。NSTimerを使用してみましたが、UIがロックされたままです。私の仕事は、チャット画面で新しいメッセージを確認することです。5秒ごとにこのタスクを呼び出す必要があります。 NSTimerを使用している場合、テキストを入力すると、このタスクの実行中にテキストが一瞬フリーズするようです。 UIをロックせずにこのタスクを処理する方法はありますか。アドバイスをお願いします。本当にありがとう。

==更新コード==

 - (void)performBackgroundTask
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //Do background work

        if([[NSUserDefaults standardUserDefaults] boolForKey:@"LoggedIn"]) {
            NSDictionary * userDictionary = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"SessionDictionary"];

            NSString *authenKey= [userDictionary valueForKey:@"authToken"];

            NSString* limit = @"1000";

            [[LSDataManager sharedDataManager] getLatestMessagesWithAuthKey:authenKey andLimit:limit withBlock:^ (NSDictionary* responseDict)
             {
                 if (responseDict) {
                     [self loadDataFromServer:responseDict];

                     NSArray* lastMessageArray= nil;

                     //filter message data
                     if (self.MessagesArray.count >0) {

                         if (!self.isSeller) {

                             lastMessageArray = [self filterMessageData:self.MessagesArray withProductID:self.productID withSellerID:self.receiverID withBuyerID:self.senderID];
                         }
                         else
                         {
                             lastMessageArray = [self filterMessageData:self.MessagesArray withProductID:self.productID withSellerID:self.senderID withBuyerID:self.receiverID];
                         }

                         NSLog(@"filter array %@",lastMessageArray);

                         if([lastMessageArray count] >0){
                             //[self loadMessages:lastMessageArray];
                             if (self.TempdataSource == nil) {
                                 self.TempdataSource = [NSMutableArray array];
                             }
                             else
                             {
                                 [self.TempdataSource removeAllObjects];
                             }

                             self.TempdataSource = [[[ContentManager sharedManager] generateConversation:lastMessageArray withSenderID:self.senderID] mutableCopy];

                         }
                     }
                 }
             }];
        }


        dispatch_async(dispatch_get_main_queue(), ^{
            //Update UI

            //compare 2 arrays
            if ([self.TempdataSource count] == [self.dataSource count]) {
                NSLog(@"both are same");
            }
            else{
                NSLog(@"both are different");
                self.dataSource = [self.TempdataSource mutableCopy];

                [self refreshMessages];
            }

        });
    });
}
18
NTNT

NSTimerを使用したタスクのスケジューリングは、まさに正しい方法です。バックグラウンドスレッドで重い非UIコ​​ードを実行していることを確認する必要があります。ここに例があります

- (void)viewDidLoad {
    [super viewDidLoad];    
    [self startTimedTask];
}

- (void)startTimedTask
{
    NSTimer *fiveSecondTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(performBackgroundTask) userInfo:nil repeats:YES];
}

- (void)performBackgroundTask
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //Do background work
        dispatch_async(dispatch_get_main_queue(), ^{
            //Update UI
        });
    });
}
34
Stavash
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    //Background Thread
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //Run UI Updates
    });
});

これを試して

15
Merlea Dan