1

我的应用程序中有一个搜索功能,用户在 textField 中键入,随着文本的更改,我正在搜索本地数据库并在表中填充数据。

根据输入的文本,搜索可能需要 1 到 10 秒,所以我决定使用线程。每次文本更改时,我都想取消线程(如果已经运行),并使用 new 关键字再次启动它。问题是根据文档调用取消不能保证线程将被杀死。那么这里的解决方案是什么?

有没有办法杀死一个线程?

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

3 回答 3

4

您不希望线程必然死亡,因为它稍后会被重用(制作线程很昂贵)。您应该做的是将您的工作分解成尽可能多的部分,并在每个部分之间检查您的线程的isCancelled属性是否为YES. 如果是这样,请在不更新的情况下返回。

[NSThread currentThread]当你在里面时应该返回你的线程populateDataInBackground

于 2012-07-19T04:26:59.127 回答
2

我最终修改了我的 dataStorage 以一次返回 10 个项目,只是为了测试。我以后可能会使用另一个号码。这样我就可以在我的 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
于 2012-07-19T06:31:11.987 回答
1

一些可能的解决方案之一包括:

BOOL从您的主线程(例如“ ”)设置一些“ ”信号量/属性,searchNow并在您执行“ populateData”后台线程/任务时定期读取它。

如果状态变为“NO”(假设“ searchNow” == YES 意味着任务应该继续),则退出您的后台线程。

于 2012-07-19T04:24:36.040 回答