2012-07-19 1 views
1

사용자가 textField에 입력하는 검색 기능이 있으며 텍스트가 변경 될 때 로컬 데이터베이스를 검색하고 테이블의 데이터를 채우는 검색 기능이 있습니다.Objective-C - 스레드 취소 중입니까?

입력 한 텍스트에 따라 검색 시간이 1 ~ 10 초 정도 걸릴 수 있으므로 스레드를 사용하기로 결정했습니다. 텍스트가 변경 될 때마다 스레드를 취소하고 (이미 실행중인 경우) 새 키워드로 다시 시작합니다. 문제는 문서 호출에 따라 cancel을 호출해도 스레드가 삭제되지 않는다는 것입니다. 그럼 여기서 해결책은 무엇입니까?

스레드를 죽일 방법이 있습니까? 몇 가지 가능한 해결책의

- (void)populateData 
{ 
    if (self.searchThread.isExecuting) 
    { 
     [self.searchThread cancel]; 
    } 

    [self.searchThread start]; 
} 

- (void)populateDataInBackground 
{ 
    @autoreleasepool 
    { 
     // get data from db 
     // populate table on main thread 
    } 
} 

답변

4

나중에 다시 사용되므로 스레드가 반드시 죽는 것을 원하지는 않습니다 (스레드를 비싸게 만드는 것). 가능한 한 많은 부분으로 작업을 중단하고 각 부분 사이에 스레드의 isCancelled 속성이 YES인지 확인하십시오. 그렇다면 업데이트하지 않고 반송하십시오. 당신이 populateDataInBackground

+0

db에서 데이터를 가져 오는 데는 한 줄의 코드가 필요하고 테이블을 채우는 데는 한 줄의 코드가 필요합니다. 나는 조각으로 분해 할 수있는 방법을 모르겠다 :) – aryaxt

+0

다음 두 줄 사이를 확인해야 할 것 같아요. 대부분의 작업이 첫 번째 단계에 있다고 생각합니다. 테이블의 업데이트는 다음과 같습니다. 사소한 일로 사형 집행을 자제 할 수는 없다는 의심의 여지가 있습니다. 스레드에서 exit를 호출 할 수는 있지만 문서는 경고하지 않습니다. 테이블을 업데이트할지 여부를 나타내는 플래그로 cancel을 사용해야 할 수도 있습니다. – borrrden

1

하나는이 포함됩니다 : 당신이 겪고있는 동안 메인 스레드에서 일부 "BOOL"세마포어/속성을 설정

(예 : "searchNow")을 주기적으로 읽어 당신의 "populateData"배경 스레드/작업.

상태가 "아니오"("searchNow"== YES이면 작업이 계속된다는 것을 의미한다고 가정)로 변경되면 백그라운드 스레드를 종료하십시오.

+0

백그라운드 스레드를 종료하려면 어떻게해야합니까? 취소는 즉시 스레드를 종료하지 않습니다. – aryaxt

+0

스레드가 어떤 루프 (예 : "do {} while (searchNow == YES); ')에서 실행 중이면 스레드가 종료되고 @ borrrden의 제안도 좋습니다 (+1). 스레드가 * 설치 비용이 많이 든다 고 생각합니다. 특히 가끔 텍스트 입력 중에 만 가져 오는 경우가 많습니다. –

2

내가 한 번에 10 개 개의 항목을 반환하는 내 데이터 저장을 수정 결국 내부에있는 동안

[NSThread currentThread]는 테스트를 위해, 당신의 스레드를 반환해야합니다. 나중에 다른 번호를 사용할 수도 있습니다. 이렇게하면 while 루프에서 스레드를 종료 할 수 있습니다.

또 다른 장점은 모든 데이터를 검색하는 것을 기다리는 대신 항목을 검색 할 때 테이블을 채울 수 있다는 것입니다.

@interface ViewController 

@property (nonatomic, strong) NSthread *searchThread; 

@end 

@implementation ViewController 
@synthesize searchThread = _searchThread; 

- (void)populateData 
{ 
    [self.searchThread cancel]; 

    self.searchThread = [[NSThread alloc] initWithTarget:self selector:@selector(populateDataInBackground) object:nil]; 
    [self.searchThread start]; 
} 

- (void)populateDataInBackground 
{ 
    @autoreleasepool 
    { 
     [self.array removeAllObjects]; 

     // I added paging functionality to my sql, so I get let's say 10 records at a time 
     while (/*has data*/) 
     { 
      NSArray *arrayOf10 = [self.dataStorage getdatafromIndex:startingIndex withCount:10]; 

      if ([[NSThread currentThread] isCancelled]) 
       [NSThread exit]; 

      [self.array addObjects:arrayOf10]; 
      [self.tableView performSelectorOnMainThread:@Selector(reloadData) withObject:nil waitUntilDone:NO]; 
     } 
    } 
} 

@end 
+0

그래서 다른 말로하면 "할 수있는 한 많은 조각으로 작업을 나누십시오";))) – borrrden

+0

예, 나중에이 참조를 게시했습니다. :) – aryaxt