2014-09-19 122 views
17

我是iOS新手。我正在研究應用程序需要在後臺線程中運行從服務器獲取數據的任務,因爲我不想在主線程中鎖定UI。這個任務將需要很長時間,我嘗試使用NSTimer,但它仍然鎖定用戶界面。我的任務是在聊天屏幕中查看新消息,我需要每5秒調用一次這個任務。如果我使用NSTimer,當輸入文本時,文本似乎在執行此任務時凍結一會兒。有沒有辦法在沒有鎖定UI的情況下處理這個任務。請給我一些建議。非常感謝。在iOS中定期在後臺線程中運行任務

==更新代碼==

- (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]; 
      } 

     }); 
    }); 
} 
+0

對不起。我不能給你一個回答你的問題。但我可以說使用NSTimer每5秒調用一次任務就會消耗資源,我不會建議你這麼做! – eliasah 2014-09-19 17:22:12

+0

@eliasah:謝謝。你有比它更好的解決方案嗎? – NTNT 2014-09-19 17:30:01

+0

@eliasah我不確定爲什麼你認爲NSTimer是資源密集型的。你有任何參考?或者你只是提到每5秒鐘做一次任何事情的想法? – 2014-09-19 17:46:28

回答

13
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ 
    //Background Thread 
    dispatch_async(dispatch_get_main_queue(), ^(void){ 
     //Run UI Updates 
    }); 
}); 

試試這個

+0

感謝您的快速回復。我試過,但它仍然是相同的 – NTNT 2014-09-19 17:14:07

34

安排使用一個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 
     }); 
    }); 
} 
+0

謝謝,但我聽說,如果使用NSTimer不好,對吧?對不起,我是IOS的新手,我只是想了解更多 – NTNT 2014-09-19 17:30:55

+0

你能添加一個引用到你聽到的這個地方嗎? – Stavash 2014-09-19 17:31:52

+0

@Stavash我說NSTimer來激活任務是資源消耗。我沒有說它不好。但我完全同意你給出的解決方案+1。 – eliasah 2014-09-19 17:32:55