Objective-C - 取消线程?

时间:2012-07-19 04:15:21

标签: objective-c ios nsthread

我的应用程序中有一个搜索功能,用户在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
   }
}

3 个答案:

答案 0 :(得分:4)

你不希望线程必然死亡,因为它将在以后重用(使线程很昂贵)。你应该做的是尽可能多地将你的工作分成几部分,并在每一部分之间检查你的线程的isCancelled属性是否为YES。如果是这样,请在没有更新的情况下返回。

当您在[NSThread currentThread]

内时,

populateDataInBackground应该返回您的帖子

答案 1 :(得分: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

答案 2 :(得分:1)

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

从主线程设置一些“BOOL”信号量/属性(例如“searchNow”),并在浏览“populateData”后台线程时定期阅读任务。

如果状态更改为“NO”(假设“searchNow”== YES表示任务应该继续),则退出后台线程。