2014-09-19 4 views
17

저는 iOS에서 새로운 기능입니다. 나는 스레드에서 UI를 잠그고 싶지 않기 때문에 백그라운드 스레드에서 서버에서 데이터를 가져 오는 작업을 실행해야합니다. 이 작업은 오래 걸릴 것입니다. NSTimer를 사용해 보았지만 여전히 UI가 잠겨 있습니다. 내 임무는 채팅 화면에서 새 메시지를 확인하는 것입니다. 매 5 초마다이 작업을 호출해야합니다. 텍스트를 입력 할 때 NSTimer를 사용하면이 작업이 수행되는 동안 텍스트가 잠시 멈추는 것처럼 보입니다. 잠금 UI없이이 작업을 처리 할 수있는 방법이 있습니까? 제게 조언 해주세요. 정말 고마워.iOS에서 주기적으로 백그라운드 스레드에서 작업 실행

NSTimer이 실제로 갈 수있는 올바른 방법이다 사용하여 작업을 예약 == UPDATE 코드 ==

- (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

+0

@eliasah : 감사합니다. 그것보다 더 좋은 해결책이 있습니까? – NTNT

+0

@eliasah NSTimer가 자원 집약적이라고 생각하는 이유가 확실하지 않습니다. 참조가 있으십니까? 아니면 5 초에 한 번 수행 할 생각입니까? –

답변

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

34

. 백그라운드 스레드에서 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

+0

당신이 이것을 들었던 곳에 대한 참조를 추가 할 수 있습니까? – Stavash

+0

@Stavash NSTimer가 작업을 활성화하려면 리소스를 많이 사용한다고했습니다. 나는 그것이 좋지 않다고 말하지 않았다. 하지만 +1 한 솔루션에 완전히 동의합니다. – eliasah

관련 문제